Berikut adalah cara yang sedikit lebih efisien untuk membagi daftar bilangan bulat. Pertama, buat tabel angka, jika Anda belum memilikinya. Ini akan membuat tabel dengan 100.000 bilangan bulat unik (Anda mungkin membutuhkan lebih atau kurang):
;WITH x AS
(
SELECT TOP (1000000) Number = ROW_NUMBER() OVER
(ORDER BY s1.[object_id])
FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
ORDER BY s1.[object_id]
)
SELECT Number INTO dbo.Numbers FROM x;
CREATE UNIQUE CLUSTERED INDEX n ON dbo.Numbers(Number);
Kemudian fungsi:
CREATE FUNCTION [dbo].[SplitInts_Numbers]
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = CONVERT(INT, SUBSTRING(@List, Number,
CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number))
FROM dbo.Numbers
WHERE Number <= CONVERT(INT, LEN(@List))
AND SUBSTRING(@Delimiter + @List, Number, 1) = @Delimiter
);
Anda dapat membandingkan kinerja dengan pendekatan berulang di sini:
http://sqlfiddle.com/#!3/960d2/1
Untuk menghindari tabel angka, Anda juga dapat mencoba versi fungsi berbasis XML - ini lebih ringkas tetapi kurang efisien:
CREATE FUNCTION [dbo].[SplitInts_XML]
(
@List VARCHAR(MAX),
@Delimiter CHAR(1)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN ( SELECT Item = CONVERT(INT, Item) FROM (
SELECT Item = x.i.value('(./text())[1]', 'int') 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
);
Pokoknya begitu Anda memiliki fungsi, Anda cukup mengatakan:
WHERE ID IN (SELECT Item FROM dbo.SplitInts_Numbers(@MyList, ','));