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 melalui 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 dapat menjadi:
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 perlu meneruskan daftar sebagai '1,2,3,12'
...
Saya menemukan metode melewati parameter bernilai tabel menyederhanakan pemeliharaan solusi yang menggunakannya dan sering meningkatkan kinerja dibandingkan dengan implementasi lain termasuk XML dan pemisahan string.
Input didefinisikan dengan jelas (tidak ada yang harus menebak apakah pembatas adalah koma atau titik koma) dan kami tidak memiliki ketergantungan pada fungsi pemrosesan lain yang tidak jelas tanpa memeriksa kode untuk prosedur tersimpan.
Dibandingkan dengan solusi yang melibatkan skema XML yang ditentukan pengguna alih-alih UDT, ini melibatkan sejumlah langkah yang serupa tetapi menurut pengalaman saya kode yang jauh lebih sederhana untuk dikelola, dipelihara, dan dibaca.
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 contoh ini, persyaratan umum adalah melewati daftar pointer ID, nama fungsi menjelaskan konteks apa yang harus diwakili oleh Id tersebut, nama tipe harus generik.