यहाँ पूर्णांकों की सूची को विभाजित करने का थोड़ा अधिक कुशल तरीका है। सबसे पहले, एक संख्या तालिका बनाएं, यदि आपके पास पहले से एक नहीं है। यह 100,000 अद्वितीय पूर्णांकों वाली एक तालिका बनाएगा (आपको अधिक या कम की आवश्यकता हो सकती है):
;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);
फिर एक समारोह:
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
);
आप प्रदर्शन की तुलना यहां एक पुनरावृत्त दृष्टिकोण से कर सकते हैं:
http://sqlfiddle.com/#!3/960d2/1
संख्या तालिका से बचने के लिए, आप फ़ंक्शन के XML-आधारित संस्करण को भी आज़मा सकते हैं - यह अधिक कॉम्पैक्ट है लेकिन कम कुशल है:
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
);
वैसे भी एक बार जब आपके पास कोई कार्य होता है तो आप बस कह सकते हैं:
WHERE ID IN (SELECT Item FROM dbo.SplitInts_Numbers(@MyList, ','));