In SQL Server 2008 and later, you can use a table valued parameter. In the database, you have to create a table type. For example:
-- Drop old example definitions
if exists (select * from sys.procedures where name = 'TestProcedure')
drop procedure TestProcedure
if exists (select * from sys.types where name = 'TestTableType')
drop type TestTableType
if exists (select * from sys.tables where name = 'TestTable')
drop table TestTable
go
-- Create example table, type and procedure
create table TestTable (id int identity, name varchar(50))
create type TestTableType as table (name varchar(50))
go
insert TestTable values ('Bill'), ('George'), ('Barrack')
go
create procedure dbo.TestProcedure
@List TestTableType readonly
as
select *
from TestTable
where name in
(
select name
from @List
)
go
In C#, you can pass a DataTable
as a table-valued parameter:
var listTable = new DataTable();
listTable.Columns.Add("Name", typeof(string));
listTable.Rows.Add("Bill");
listTable.Rows.Add("George");
var listParameter = new SqlParameter();
listParameter.ParameterName = "@List";
listParameter.Value = listTable;
using (var con = new SqlConnection("Server=localhost;Database=test;" +
"User Id=testuser;Password=testpassword;"))
{
var com = con.CreateCommand();
com.CommandText = "dbo.TestProcedure";
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add(listParameter);
con.Open();
using (var read = com.ExecuteReader())
{
while (read.Read())
Console.WriteLine(read["name"]);
}
}
The amount and complexity of code required for even a single table-valued parameter is no complement for the SQL Server designers.