I have a query where I want to return all the rows which are associated with a list of values. You could write this very simply as:
select * from TableA whe
You can also use multiple resultsets and send a bounch of query like this:
select * from TableA where ColumnB = @value0
select * from TableA where ColumnB = @value1
select * from TableA where ColumnB = @value2
...
select * from TableA where ColumnB = @valuen
in a single call. even if apparently counter intuitive it leverages execution plan and is safe in term of parametrization.
You can easily write this:
String csvString = "1, 2, 3, 5"; // Built the list somehow, don't forget escaping
String query = "select * from TableA where ColumnB in (" + csvString + ")";
By this way, performance doesn't decreased, and you can prevent Sql Injection simply escaping input values while creating csvString
.
BTW, if you use MS SQL instead of standard SQL, you can find alternative ways.
Assuming SQL Server 2008 or newer, in SQL Server, create a table type once:
CREATE TYPE dbo.ColumnBValues AS TABLE
(
ColumnB INT
);
Then a stored procedure that takes such a type as input:
CREATE PROCEDURE dbo.whatever
@ColumnBValues dbo.ColumnBValues READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT A.* FROM dbo.TableA AS A
INNER JOIN @ColumnBValues AS c
ON A.ColumnB = c.ColumnB;
END
GO
Now in C#, create a DataTable and pass that as a parameter to the stored procedure:
DataTable cbv = new DataTable();
cbv.Columns.Add(new DataColumn("ColumnB"));
// in a loop from a collection, presumably:
cbv.Rows.Add(someThing.someValue);
using (connectionObject)
{
SqlCommand cmd = new SqlCommand("dbo.whatever", connectionObject);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter cbvParam = cmd.Parameters.AddWithValue("@ColumnBValues", cbv);
cbvParam.SqlDbType = SqlDbType.Structured;
//cmd.Execute...;
}
(You might want to make the type a lot more generic, I named it specifically to make it clear what it is doing.)