SQL Server 2008 (atau lebih baru)
Pertama, di database Anda, buat dua objek berikut:
CREATE TYPE dbo.IDList
AS TABLE
(
ID INT
);
GO
CREATE PROCEDURE dbo.DoSomethingWithEmployees
@List AS dbo.IDList READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT ID FROM @List;
END
GO
Sekarang dalam kode C # Anda:
// Obtain your list of ids to send, this is just an example call to a helper utility function
int[] employeeIds = GetEmployeeIds();
DataTable tvp = new DataTable();
tvp.Columns.Add(new DataColumn("ID", typeof(int)));
// populate DataTable from your List here
foreach(var id in employeeIds)
tvp.Rows.Add(id);
using (conn)
{
SqlCommand cmd = new SqlCommand("dbo.DoSomethingWithEmployees", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvparam = cmd.Parameters.AddWithValue("@List", tvp);
// these next lines are important to map the C# DataTable object to the correct SQL User Defined Type
tvparam.SqlDbType = SqlDbType.Structured;
tvparam.TypeName = "dbo.IDList";
// execute query, consume results, etc. here
}
SQL Server 2005
Jika Anda menggunakan SQL Server 2005, saya masih akan merekomendasikan fungsi split atas XML. Pertama, buat fungsi:
CREATE FUNCTION dbo.SplitInts
(
@List VARCHAR(MAX),
@Delimiter VARCHAR(255)
)
RETURNS TABLE
AS
RETURN ( SELECT Item = CONVERT(INT, Item) FROM
( SELECT Item = x.i.value('(./text())[1]', 'varchar(max)')
FROM ( SELECT [XML] = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>') + '</i>').query('.')
) AS a CROSS APPLY [XML].nodes('i') AS x(i) ) AS y
WHERE Item IS NOT NULL
);
GO
Sekarang prosedur tersimpan Anda bisa saja:
CREATE PROCEDURE dbo.DoSomethingWithEmployees
@List VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
SELECT EmployeeID = Item FROM dbo.SplitInts(@List, ',');
END
GO
Dan dalam kode C # Anda, Anda hanya harus melewati daftar sebagai '1,2,3,12'
...
Saya menemukan metode melewati tabel nilai parameter menyederhanakan rawatan dari solusi yang menggunakannya dan sering memiliki peningkatan kinerja dibandingkan dengan implementasi lain termasuk XML dan pemisah string.
Input didefinisikan dengan jelas (tidak ada yang harus menebak jika pembatas adalah koma atau semi-kolon) dan kami tidak memiliki ketergantungan pada fungsi pemrosesan lain yang tidak jelas tanpa memeriksa kode untuk prosedur yang tersimpan.
Dibandingkan dengan solusi yang melibatkan skema XML yang ditentukan pengguna dan bukan UDT, ini melibatkan sejumlah langkah yang sama tetapi dalam pengalaman saya adalah kode yang jauh lebih sederhana untuk mengelola, memelihara, dan membaca.
Dalam banyak solusi, Anda mungkin hanya memerlukan satu atau beberapa UDT ini (Jenis yang ditentukan pengguna) yang Anda gunakan kembali untuk banyak prosedur tersimpan. Seperti halnya contoh ini, persyaratan umum adalah untuk melewati daftar ID pointer, nama fungsi menjelaskan konteks apa yang harus diwakili Id, tipe nama harus generik.