Recently I found myself in C#, doing some SQL. This is not exactly my area of expertise. I wrote some code that looks pretty ugly, and am failing to find a better solution anyplace. Many of the answers here on SO pose SQL injection risks, and are essentially doing the same thing im doing in one way or another. The situation is, I have a form which a user provides a list of Store ID's in a form. When they click a button, a CSV export will be generated using the stores they provide as exclusion criteria for the query. The way I accomplished this is by setting up my SQL string as a constant, then using a string builder to dynamically append @X
in an IN
clause. The code looks fairly bad but heres a quick snippet to better explain. For example, say the SQL query is this
private readonly String _SELECT_UNEXPECTED_TOTES = "SELECT * FROM TABLE WHERE TABLE.Store IN ";
I then do the following (stores is an array of strings, sb is a string builder):
//get enough room for all the stores
var sqlParams = new SqlParameter[stores.Length];
conn.Open();
//append our query
sb.Append(_SELECT_UNEXPORTED_TOTES);
//open the IN list
sb.Append("(");
//build the in list
int I = 0;
foreach (String s in stores)
{
sb.Append("@");
sb.Append(I);
sb.Append(",");
I++;
}
//trim the trailing ,
sb.Length -= 1;
sb.Append(")");
//make the actual parameters
I = 0;
foreach (String s in stores)
{
sqlParams[I] = new SqlParameter("@" + I, SqlDbType.VarChar);
sqlParams[I].Value = s;
I++;
}
Later on in code I then use these SQL params in a SqlStatement object. Does .NET provide a better way to accomplish this? I dont know a lot about .NETs SQL objects, and for all I know this solution could be just as bad as a simple string replace... Any advice is welcome.