How to insert a ICollection<string> into one Field in ADO.NET? - c#

I have ICollection object in my controller. This collection posted from view like this;
{string[3]}
[0]=a
[1]=b
[2]=c
public ActionResult TarifEkle(Tarifler tarif, ICollection<string> tAdim)
{
string mainconn = ConfigurationManager.ConnectionStrings["Tarif"].ConnectionString;
SqlConnection sqlconn = new SqlConnection(mainconn);
string sqlquery = "insert into [NePisirsem].[dbo].[Tarifler](tAdim) values (#builder)";
SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn);
sqlconn.Open();
I change this value like this a,b,c with my builder;
var builder = new System.Text.StringBuilder();
foreach (string item in tAdim)
{
builder.Append(item).Append(",");
sqlcomm.Parameters.AddWithValue("#builder", tarif.tAdim);
}
It works values are successfully became i want (a,b,c) but I can't add this values this way a,b,c
sqlcomm.Parameters.AddWithValue("#builder", tarif.tAdim); this code takes always just first value a not all of them.
How can i do?

You need tho change the following section
var builder = new System.Text.StringBuilder();
foreach (string item in tAdim)
{
builder.Append(item).Append(",");
sqlcomm.Parameters.AddWithValue("#builder", tarif.tAdim);
}
to
sqlcomm.Parameters.AddWithValue("#builder", string.Join(",", tAdim));
#builder will then be replaced by a,b,c in your sqlquery if you need a, b, c replace "," with ", ". Read more about string.Join() here.
Don't use AddWithValue()
As you can read here, you should prefere Parameters.Add() over Parameters.AddWithValue() as you can specify the appropriate SqlDbType that your string is converted to.
sqlcomm.Parameters.Add("#builder", SqlDbType.VarChar, 30).Value = string.Join(",", tAdim);
Either use SqlDbType.VarChar or SqlDbType.NVarChar and replace 30 with your actual max lenght.
INSERT INTO Statement
As explained here, the format of an insert statement looks like this:
INSERT INTO table_name (column_list)
VALUES
(value_list_1),
(value_list_2),
...
(value_list_n);
column_list is a list of Columns that in your case are on [NePisirsem].[dbo].[Tarifler] e.g. tAdim. Then multiple value_lists can be supplied, each generating a new row in your table. value_list needs to match the order of column_list

Related

Add listbox item to SQL Server columns as columns name

foreach (string LB in listBox1.Items)
{
SqlCommand SCA = new SqlCommand("create table " + textBox3.Text + "("+
listBox1.Items[].ToString()+")",SC1);
SCA.ExecuteNonQuery();
}
How to add all items using loop to add items on listbox.items to SQL Server columns for columns name only?
Example:
You are trying to create several tables with the same name in a loop. I suppose your code should look something like that:
// StringBuilder is better way to creating a string in a loop,
// because it doesn't allocate new string on each concatenation
StringBuilder command = new StringBuilder("create table ");
command.Append(textBox3.Text).Append("(");
string separator = "";
// It is better to give more descriptive names to variables
foreach (string columnName in listBox1.Items)
{
// You forgot to specify column type
command.Append(separator)
.Append(columnName)
.Append(" varchar(1000)");
separator = ",";
}
command.Append(")");
// SqlCommand and SqlConnection implement IDisposable,
// so it is better to wrap their instantiation by 'using' statement
// in order to free corresponding resources
using (SqlCommand sqlCommand = new SqlCommand(command.ToString(), SC1)) {
sqlCommand.ExecuteNonQuery();
}

SELECT statement not returning anything

My issue is that the results are empty when executing the statement, even though when executing it in Microsoft's SQL server studio it works.
//This has two values in it (Ex: 4 and 2)
string[] arr2 = groupListValues.Split('-');
List<string> userID = new List<string>();
// Connect to the database
SqlConnection gconn = new SqlConnection(ConfigurationManager.ConnectionStrings["connectinfohere"].ConnectionString);
gconn.Open();
SqlCommand command1 = new SqlCommand();
command1.Connection = gconn;
String sql = "SELECT ID FROM Users WHERE Group = #groupID";
command1.CommandText = sql;
command1.Parameters.Add(new SqlParameter("#groupID", ""));
SqlDataReader reader = command1.ExecuteReader();
//issue is in this loop
foreach (string str in arr2)
{
command1.Parameters["#groupID"].Value = str;
while (reader.Read())
{
userID.Add(reader["ID"].ToString());
}
}
Not sure what the issue is. The "ID" I'm getting in the SQL statement is of type bigint, could that cause an issue?
The reason I am setting the parameter inside the foreach loop is because, for each value in arr2 corresponds to a group that several users could be attached to. So I need to loop through that, get the users attached to each groupID, then add all their ID's to a list.
There are two problems with you code:
The first one is that you setting the #groupID parameter after you execute the reader. To fix it, execute the reader after you set the parameter value like this:
foreach (string str in arr2)
{
command1.Parameters["#groupID"].Value = str;
using(SqlDataReader reader = command1.ExecuteReader())
{
while (reader.Read())
{
userID.Add(reader["ID"].ToString());
}
}
}
The second problem is that Group is a reserved keyword in SQL, so you need to wrap it with square brackets like this:
String sql = "SELECT ID FROM Users WHERE [Group] = #groupID";

SqlCommand AddWithValue not working properly

I have the following block of code... fieldCount always returns 0.
I suspect AddWithValue isn't forming the SELECT statement properly... Any ideas why? As you can see from the Watch, they (field, fieldId) have valid values.
public void deleteRows(string table, string field, string fieldId)
{
int fieldCount;
using (SqlCommand command = new SqlCommand(String.Format("SELECT COUNT(*) FROM {0} WHERE #field IN (#fieldId)", table), connection))
{
command.Parameters.AddWithValue("#field", field);
command.Parameters.AddWithValue("#fieldId", fieldId);
fieldCount = (int)command.ExecuteScalar();
}
if (fieldCount > 0)
{
There are two errors in your code:
First, you cannot use a parameter to express a table name or a column name. So your field parameter is not valid in this context.
Second, you cannot use a parameter to express the whole set of values for the IN clause. In your example the parameter #fieldID will be translated in
WHERE ..... IN ('1,2,3,4')
It will be treated as a string not as the individual values to be included in your where context-
For the field part, if you are absolutely sure that the string field parameter passed to your method is not typed directly by your user then you could use a string concatenation expression (well you are already doing this for the table so the warning is good also for that value)
String.Format("SELECT COUNT(*) FROM {0} WHERE {1} IN (....)", table, field);
For the IN part, I suggest, instead of passing the string, to build, in the calling function, a list of parameters to be added at the query.
public void deleteRows(string table, string field, List<SqlParameter> inParameters)
{
StringBuilder sb new StringBuilder();
sb.AppendFormat("SELECT COUNT(*) FROM {0} WHERE {1} IN (", table, field));
using(SqlCommand cmd = new SqlCommand())
{
cmd.Connection = connection;
// Loop over the parameter list, adding the parameter name to the
// IN clause and the parameter to the SqlCommand collection
foreach(SqlParameter p in inParameters)
{
sb.Append(p.Name + ",");
cmd.Parameters.Add(p);
}
// Trim out the last comma
sb.Length--;
// Close the IN clause
sn.Append(")";
cmd.CommandText = sb.ToString();
fieldCount = (int)command.ExecuteScalar();
}
}

Parametized SQL Query with unlimited parameters

I've heard of parametized sql queries a long time ago but I never really gave any attention to it as I'm used to writing full sql statements. I know it improves security against sql injection so now might be a very good time to adapt change even if it's too late. I got this one from this site http://www.codinghorror.com/blog/2005/04/give-me-parameterized-sql-or-give-me-death.html. So all credits go to the author. I've noticed all examples of parametized sql queries have paremeter count limitations. An example is the one shown below.
SqlConnection conn = new SqlConnection(_connectionString);
conn.Open();
string s = "SELECT email, passwd, login_id, full_name FROM members WHERE email = #email";
SqlCommand cmd = new SqlCommand(s);
cmd.Parameters.Add("#email", email);
SqlDataReader reader = cmd.ExecuteReader();
This is just equivalent to
SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x';
I've learned programming all on my own through reading online tutorials and I really got nobody to help me on this. The reason I got stuck with full sql statement queries is the fact that I can't figure out how to do parametized sql queries with unlimited parameters. Is there any way to do this? The example only accepts 1 parameter which is the 'email' field. And it selects 4 fields from the given sql statement. My question is... is there any way we can do parametized sql queries with 5, 6, 7, or 100 selected fields, as well as the conditions under the WHERE clause? If this is possible, it will be particularly helpful when using INSERT statement. Thank you very much.
This example is in C#, but any VB.NET or same C# implementations are greatly appreciated. Thanks.
One possible solution would be to pass the parameters name and value using a Dictionary object. A Dictionary object holds a collection of keys and values, and this is exactly what a single SqlParameter is - a single Key/Value container in the form:
Key = #Value
A collection can hold an arbitrary count of items, for example:
new Dictionary<String, Object>
{
{ "#Name", "Anonymous" },
{ "#Age", 25 },
{ "#Street", "Highway" },
{ "#Number", "1001" },
{ "#City", "NoName" }
}
In the example above, the key is of type String and the value of type Object. Object allows parameter values of arbitrary types (the explanation comes later in the code examples).
One possibility to create dynamic SQL statements would be:
extract the repetitive tasks, for example the creation of the SqlCommand and the passing of the parameters to the SqlCommand variable
create parametrised dynamic SQL query string for the wanted SQL command
The code can look like this:
// extract all repetitive tasks
// Create an array of SqlParameters from the given Dictionary object.
// The parameter value is of type Object in order to allow parameter values of arbitrary types!
// The .NET Framework converts the value automatically to the correct DB type.
// MSDN info: http://msdn.microsoft.com/en-us/library/0881fz2y%28v=vs.110%29.aspx
private SqlParameter[] dictionaryToSqlParameterArray(Dictionary<string, object> parameters)
{
var sqlParameterCollection = new List<SqlParameter>();
foreach (var parameter in parameters)
{
sqlParameterCollection.Add(new SqlParameter(parameter.Key, parameter.Value));
}
return sqlParameterCollection.ToArray();
}
// sqlQuery is the complete parametrised query
// for example like: INSERT INTO People(Name, Age, Street) VALUES(#Name, #Age, #Street)
private SqlCommand createSqlCommand(String sqlQuery, Dictionary<String, object> parameters)
{
SqlCommand command = new SqlCommand(sqlQuery);
command.Parameters.AddRange(dictionaryToSqlParameterArray(parameters));
return command;
}
Now a call with dynamic count of parameters will look like this:
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
string sqlQuery = "SELECT email, passwd, login_id, full_name FROM members WHERE email = #email AND name = #name";
// using the newly created method instead of adding/writing every single parameter manually
SqlCommand command = createSqlCommand(sqlQuery, new Dictionary<String, Object>
{
{ "#email", "test#test.com" },
{ "#name", "test" }
});
SqlDataReader reader = command.ExecuteReader();
It is a good start, but this is still not very dynamic, since we need to write the complete query every time (we save only the typing of command.Parameters.Add). Let's change this in order to type even less:
// create a parametrised SQL insert command with arbitrary count of parameters for the given table
private SqlCommand createSqlInsert(String tableName, Dictionary<String, object> parameters)
{
// the sql insert command pattern
var insertQuery = #"INSERT INTO {0}({1}) VALUES({2})";
// comma separated column names like: Column1, Column2, Column3, etc.
var columnNames = parameters.Select (p => p.Key.Substring(1)).Aggregate ((h, t) => String.Format("{0}, {1}", h, t));
// comma separated parameter names like: #Parameter1, #Parameter2, etc.
var parameterNames = parameters.Select (p => p.Key).Aggregate ((h, t) => String.Format("{0}, {1}", h, t));
// build the complete query
var sqlQuery = String.Format(insertQuery, tableName, columnNames, parameterNames);
// debug
Console.WriteLine(sqlQuery);
// return the new dynamic query
return createSqlCommand(sqlQuery, parameters);
}
// create a parametrised SQL select/where command with arbitrary count of parameters for the given table
private SqlCommand createSqlWhere(String tableName, Dictionary<String, object> parameters)
{
// the sql select command pattern
var whereQuery = #"SELECT * FROM {0} WHERE {1}";
// sql where condition like: Column1 = #Parameter1 AND Column2 = #Parameter2 etc.
var whereCondition = parameters.Select (p => String.Format("{0} = {1}", p.Key.Substring(1), p.Key)).Aggregate ((h, t) => String.Format("{0} AND {1}", h, t));
// build the complete condition
var sqlQuery = String.Format(whereQuery, tableName, whereCondition);
// debug
Console.WriteLine(sqlQuery);
// return the new dynamic query
return createSqlCommand(sqlQuery, parameters);
}
Now the creation of a SELECT command will look like this:
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
// specify only table name and arbitrary count of parameters
var getPersonSqlCommand = createSqlWhere("People", new Dictionary<String, Object>
{
{ "#Name", "J.D." },
{ "#Age", 30 }
});
SqlDataReader reader = getPersonSqlCommand.ExecuteReader();
The createSqlWhere method will return an initialized SqlCommand with the query:
SELECT * FROM People WHERE Name = #Name AND Age = #Age
The INSERT will also be short:
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
// specify only table name and arbitrary count of parameters
var addPersonSqlCommand = createSqlInsert("People", new Dictionary<String, Object>
{
{ "#Name", "Anonymous" },
{ "#Age", 25 },
{ "#Street", "Test" }
});
addPersonSqlCommand.ExecuteNonQuery();
The corresponding SQL command will look like this:
INSERT INTO People(Name, Age, Street) VALUES(#Name, #Age, #Street)
Other SQL commands like DELETE, UPDATE and so on can be created in the same way. New parameters should be added only in one place - in the dictionary.
Admittedly the initial effort is more than just writing one method, but it will pay off if the new methods are used more than once (a couple of times) - for example five parametrised selects and/or inserts on five different tables with different parameters, which is certainly always the case in small and average sized software projects.
Just create a method like :
public void unlimQuery(string query,params object[] args)
{
SqlConnection conn = new SqlConnection(_connectionString);
conn.Open();
string s =query;
SqlCommand cmd = new SqlCommand(s);
For(int i=0;i< args.Length;i++)
cmd.Parameters.Add("#param"+i, args[i]);
SqlDataReader reader = cmd.ExecuteReader();
}
Example :
unlimQuery("INSERT INTO CUSTOMERS(ID,NAME,AGE,ADRESS,COUNTRY) VALUES(#param0,#param1,#param2,#param3,#param4)",5,"Ali",27,"my City","England");
Explanation :
the params keyword in c# gives you the possibility to insert unlimited arguments of the indicated type, so the arguments added (5,"Ali",27,"my City","England") will be casted to an array of objects then passed to the Method
inside the method you'll get an array of objects, so for each object you create a parameter, his alias is #paramX where X is the index of the argument (in the params array), then sqlCommad will replace each alias by its value defined in the cmd.Parameters.Add("#param"+i, args[i]) clause
so #param0 => 5, .....
i think you just have to change this
cmd.Parameters.Add("#email", email);
to
cmd.Parameters.AddWithValue("#email", email);

Add values to a table cell using C#

I want to add multiple values to a table cell separated by commas, the table I got is
Id ,Name , Type . I want to add multiple names in the name column, so the row will be something like:
ID Name Type
1 Peter, Jas , Roden , Karen Class A
I have done simple insertion which is:
[WebMethod]
public static string Insertion(string Name)
{
//List<string> result = new List<string>();
SqlConnection con = new SqlConnection("Data Source=XXX;Initial Catalog=XXX;User ID=sa;Password=XXXXX");
{
string query = "Insert into TestTable values #Name";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = Name;
{
con.Open();
cmd.ExecuteNonQuery();
//test();
con.Close();
return "True";
}
}
}
Can any one guide me on how to add multiple names which should be separated by commas, also I need to make sure there is no duplication of names.
you can send parameter value as "Peter, Jas , Roden , Karen" then it will insert that text in to given record.
but if you have array or List of names to be added, you can easily create the insert string as below
var names = string.Join("," ,namesArray.Distinct());
now you can call the service method using above generated names string
Can any one guide me on how to add multiple names which should be separated by commas
You need to use parameterized queries. It will also help you inb avoiding sql injection attacks.
like
cmd.Parameters.AddWithValue("#name",name);
also i need to make sure there is no duplication of names
Something like this should work for you
string name = "a,b,c,d,a,b,c,d";
HashSet<string> h = new HashSet<string>(name.Split(','));
string distinctNames = string.Join(",", h);

Categories