tags:

views:

289

answers:

7

Hi all

I am trying to pass array parameter to SQL commnd in C# like below, but it does not work. Does anyone meet it before?

string sqlCommand = "SELECT * from TableA WHERE Age IN (@Age)";
SqlConnection sqlCon = new SqlConnection(connectString);
SqlCommand sqlComm = new SqlCommand();
sqlComm.Connection = sqlCon;
sqlComm.CommandType = System.Data.CommandType.Text;
sqlComm.CommandText = sqlCommand;
sqlComm.CommandTimeout = 300;
sqlComm.Parameters.Add("@Age", SqlDbType.NVarChar);
StringBuilder sb = new StringBuilder();
foreach (ListItem item in ddlAge.Items)
{
     if (item.Selected)
     {
         sb.Append(item.Text + ",");
     }
}

sqlComm.Parameters["@Age"].Value = sb.ToString().TrimEnd(',');

Best Regadrs,

A: 

Use .AddWithValue(), So:

sqlComm.Parameters.AddWithValue("@Age", sb.ToString().TrimEnd(','));

Alternatively, you could use this:

sqlComm.Parameters.Add(
    new SqlParameter("@Age", sb.ToString().TrimEnd(',')) { SqlDbType = SqlDbType. NVarChar }
    );

Your total code sample will look at follows then:

string sqlCommand = "SELECT * from TableA WHERE Age IN (@Age)";
SqlConnection sqlCon = new SqlConnection(connectString);
SqlCommand sqlComm = new SqlCommand();
sqlComm.Connection = sqlCon;
sqlComm.CommandType = System.Data.CommandType.Text;
sqlComm.CommandText = sqlCommand;
sqlComm.CommandTimeout = 300;

StringBuilder sb = new StringBuilder();
foreach (ListItem item in ddlAge.Items)
{
     if (item.Selected)
     {
         sb.Append(item.Text + ",");
     }
}

sqlComm.Parameters.AddWithValue("@Age", sb.ToString().TrimEnd(','));

// OR

// sqlComm.Parameters.Add(new SqlParameter("@Age", sb.ToString().TrimEnd(',')) { SqlDbType = SqlDbType. NVarChar });
Kyle Rozendo
I have tried this one, does not work.
Yongwei Xing
The Age field's type is nvchar not int. Does it matter?
Yongwei Xing
It shouldn't. Especially with the second method. You specify the type explicitly.
Kyle Rozendo
I use both method, it still doesn't work. I do not want to manipulate the string which may led security problem
Yongwei Xing
I'm not really understanding you. When you say it doesn't work, does it throw an exception? What does it do?
Kyle Rozendo
it does not throw exception, it return nothing. But I run the T-SQL in Studio Management, it returns many result.
Yongwei Xing
A: 

try it like this

StringBuilder sb = new StringBuilder(); 
foreach (ListItem item in ddlAge.Items) 
{ 
     if (item.Selected) 
     { 
          string sqlCommand = "SELECT * from TableA WHERE Age IN (@Age)"; 
          SqlConnection sqlCon = new SqlConnection(connectString); 
          SqlCommand sqlComm = new SqlCommand(); 
          sqlComm.Connection = sqlCon; 
          sqlComm.CommandType = System.Data.CommandType.Text; 
          sqlComm.CommandText = sqlCommand; 
          sqlComm.CommandTimeout = 300; 
          sqlComm.Parameters.Add("@Age", SqlDbType.NVarChar);
          sb.Append(item.Text + ","); 
          sqlComm.Parameters["@Age"].Value = sb.ToString().TrimEnd(',');
     } 
} 
Ballin
Why put the SqlConnection and SqlCommnad in the loop?
Yongwei Xing
A: 

sorry how do you add code?

    StringBuilder sb = new StringBuilder(); foreach (ListItem item in ddlAge.Items) 
{ 
if (item.Selected) 
{ 
string sqlCommand = "SELECT * from TableA WHERE Age IN (@Age)";
 SqlConnection sqlCon = new SqlConnection(connectString); 
SqlCommand sqlComm = new SqlCommand(); 
sqlComm.Connection = sqlCon; sqlComm.CommandType = System.Data.CommandType.Text; sqlComm.CommandText = sqlCommand; 
sqlComm.CommandTimeout = 300; 
sqlComm.Parameters.Add("@Age", SqlDbType.NVarChar); 
sb.Append(item.Text + ","); sqlComm.Parameters["@Age"].Value = sb.ToString().TrimEnd(','); 
} 
}
Ballin
it does not work also
Yongwei Xing
+1  A: 

You will need to add the values in the array one at a time.

var parameters = new string[items.Length];
var cmd = new SqlCommand();
for (int i = 0; i < items.Length; i++)
{
    parameters[i] = string.Format("@Age{0}", i);
    cmd.Parameters.AddWithValue(parameters[i], items[i]);
}

cmd.CommandText = string.Format("SELECT * from TableA WHERE Age IN ({0})", string.Join(", ", parameters));
cmd.Connection = new SqlConnection(connStr);
Brian
Does this method have the security issue, like sql injection?
Yongwei Xing
Because you are putting the values into parameters there is no risk of sql injection.
Brian
A: 

i see, you want to pass make the parameter = to the whole string from the stringbuilder

Ballin
A: 

try

sqlComm.Parameters["@Age"].Value = sb.ToString().Replace(","," ");
Ballin
A: 

I know this has nothing to do with the question but seriously look into an orm solution like Nhibernate, Linq to SQL, LLBLGen Pro or entity framework.

It will make your life much simpler and more productive.

Just my two cents.

SetiSeeker
Do you mean that I can not solve this problem if I just use this method?
Yongwei Xing
if you use an ORM tool the sql heavy lifting like you did above is no longer needed. your specific issue seems to have been answered with the other post. my post was merely suggesting alternative aproaches to data access.
SetiSeeker