''The variable name '@' has already been declared. Variable names must be unique within a query batch or stored procedure.'
string subject= "INSERT INTO Subjects (ThesisNo, [Subject]) VALUES (2, @subject)";
SqlCommand commandSubject = new SqlCommand(subject,con);
string temp;
foreach (var control in checkedListBox.CheckedItems)
{
temp = control.ToString();
commandSubject.Parameters.AddWithValue("@subject", temp);
}
con.Open();
commandSubject.ExecuteNonQuery();
con.Close();
I want to add items that are checked in the Checkedlistbox to @subject
.
But I can only add one item. How can I add all checked items to @subject
?
Solution 1:[1]
You're adding parameters inside the loop. Add outside, and set the value inside and execute every time:
using(SqlConnection con = ...) {
string subject= "INSERT INTO Subjects(ThesisNo,[Subject]) VALUES (2, @subject)";
con.Open();
SqlCommand commandSubject = new SqlCommand(subject,con);
commandSubject.Parameters.Add("@subject", SqlDbType.VarChar);
foreach (var control in checkedListBox.CheckedItems)
{
commandSubject.Parameters["@subject"].Value = control.ToString();
commandSubject.ExecuteNonQuery();
}
}
Or if you're wanting to execute once you need to modify the SQL, and add as you go, so that you end up with an SQL like e.g. INSERT INTO .. VALUES (2,@p0), (2,@p1), (2,@p2)
and a parameters collection that is 3 long (@p0 to @p2) with 3 different data values:
using(SqlConnection con = ...) {
string subject= "INSERT INTO Subjects(ThesisNo,[Subject])VALUES";
SqlCommand commandSubject = new SqlCommand(subject, con);
int p=0;
foreach (var control in checkedListBox.CheckedItems)
{
commandSubject.CommandText += $"(2,@subject{p}),"
commandSubject.Parameters.Add($"@subject{p}", SqlDbType.VarChar).Value = control.ToString();
p++;
}
commandSubject.CommandText = commandSubject.CommandText.TrimEnd(','); //remove trailing comma from concat
con.Open();
commandSubject.ExecuteNonQuery();
}
If you have thousands of these string concats to do, use a StringBuilder. For what you might reasonably want a user to tick in a UI (20 or fewer?) string concat will be fine
Solution 2:[2]
The best method depends on whether the number of items is large and variable.
If that is the case either a Table-Valued Parameter or using SqlBulkCopy
is the most performant option.
Here is how you would do SqlBulkCopy
:
var table = new DataTable{
Columns = {
{"ThesisNo", typeof(int)},
{ "Subject", typeof(string)
}
};
foreach (var control in checkedListBox.CheckedItems)
DataTable.Rows.Add(2, control.ToString());
using(var bulk = new SqlBulkCopy(con, SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.FireTriggers)
{
DestinationTableName = "Subjects"
})
bulk.WriteToServer(table);
The other method, which, at a push, you can get away with on smaller sets, is to add a numbered parameter for each item. The maximum is 2100. Do NOT do this if range of possible rowcounts is large, otherwise you will kill your query plan store:
using(SqlCommand comm = new SqlCommand("",con))
{
var n = 0;
foreach (var control in checkedListBox.CheckedItems)
comm.Parameters.Add("@subject" + (++n), SqlDbType.Varchar, *sizeofcolumnhere*).Value = control.ToString();
comm.CommandText = "INSERT INTO Subjects(ThesisNo,[Subject])\r\nVALUES\r\n" +
string.Join("\r\n",
Enumerable.Range(1, n).Select(i => $"(2 ,@subject{i})");
comm.ExecuteNonQuery();
}
Solution 3:[3]
It's been a long time since the problem. Maybe it will be helpful for newbies. Add the line 'SqlCommand commandSubject = new SqlCommand(subject,con)' to the foreach loop. As follows.
string subject= "INSERT INTO Subjects (ThesisNo, [Subject]) VALUES
(2, @subject)";
string temp;
foreach (var control in checkedListBox.CheckedItems)
{
SqlCommand commandSubject = new SqlCommand(subject,con);
temp = control.ToString();
commandSubject.Parameters.AddWithValue("@subject", temp);
}
con.Open();
commandSubject.ExecuteNonQuery();
con.Close();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 |