आपको टीएसक्यूएल में स्ट्रिंग को विभाजित और संसाधित करने का एक तरीका चाहिए, ऐसा करने के कई तरीके हैं। इस लेख में लगभग हर विधि के पेशेवरों और विपक्षों को शामिल किया गया है:
एसक्यूएल सर्वर 2005 और उसके बाद की सरणियाँ और सूचियाँ
आपको एक स्प्लिट फ़ंक्शन बनाने की आवश्यकता है। स्प्लिट फ़ंक्शन का उपयोग इस प्रकार किया जा सकता है:
SELECT
*
FROM YourTable y
INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value
मैं टीएसक्यूएल में एक स्ट्रिंग को विभाजित करने के लिए संख्या तालिका दृष्टिकोण को प्राथमिकता देता हूं - एक का उपयोग करना संख्याओं की तालिका लेकिन SQL सर्वर में स्ट्रिंग्स को विभाजित करने के कई तरीके हैं, पिछला लिंक देखें, जो प्रत्येक के पेशेवरों और विपक्षों की व्याख्या करता है।
Numbers Table मेथड के काम करने के लिए, आपको यह एक टाइम टेबल सेटअप करना होगा, जो एक टेबल Numbers
बनाएगा। जिसमें 1 से 10,000 तक की पंक्तियाँ हों:
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
Numbers टेबल सेट हो जाने के बाद, इस स्प्लिट फंक्शन को बनाएं:
CREATE FUNCTION inline_split_me (@SplitOn char(1),@param varchar(7998)) RETURNS TABLE AS
RETURN(SELECT substring(@SplitOn + @param + ',', Number + 1,
charindex(@SplitOn, @SplitOn + @param + @SplitOn, Number + 1) - Number - 1)
AS Value
FROM Numbers
WHERE Number <= len(@SplitOn + @param + @SplitOn) - 1
AND substring(@SplitOn + @param + @SplitOn, Number, 1) = @SplitOn)
GO
अब आप आसानी से CSV स्ट्रिंग को तालिका में विभाजित कर सकते हैं और उसमें शामिल हो सकते हैं:
select * from dbo.inline_split_me(';','1;22;333;4444;;') where LEN(Value)>0
आउटपुट:
Value
----------------------
1
22
333
4444
(4 row(s) affected)
आपको नई तालिका बनाने के लिए इसका उपयोग करें:
--set up tables:
DECLARE @Documents table (DocumentID varchar(500), SomeValue varchar(5))
INSERT @Documents VALUES ('1,2,3,4','AAA')
INSERT @Documents VALUES ('5,6' ,'BBBB')
DECLARE @NewDocuments table (DocumentID int, SomeValue varchar(5))
--populate NewDocuments
INSERT @NewDocuments
(DocumentID, SomeValue)
SELECT
c.value,a.SomeValue
FROM @Documents a
CROSS APPLY dbo.inline_split_me(',',a.DocumentID) c
--show NewDocuments contents:
select * from @NewDocuments
आउटपुट:
DocumentID SomeValue
----------- ---------
1 AAA
2 AAA
3 AAA
4 AAA
5 BBBB
6 BBBB
(6 row(s) affected)
यदि आप एक नंबर टेबल नहीं बनाना चाहते हैं और SQL सर्वर 2005 और ऊपर चला रहे हैं, तो आप बस इस स्प्लिट फ़ंक्शन का उपयोग कर सकते हैं (कोई संख्या तालिका आवश्यक नहीं):
CREATE FUNCTION inline_split_me (@SplitOn char(1),@String varchar(7998))
RETURNS TABLE AS
RETURN (WITH SplitSting AS
(SELECT
LEFT(@String,CHARINDEX(@SplitOn,@String)-1) AS Part
,RIGHT(@String,LEN(@String)-CHARINDEX(@SplitOn,@String)) AS Remainder
WHERE @String IS NOT NULL AND CHARINDEX(@SplitOn,@String)>0
UNION ALL
SELECT
LEFT(Remainder,CHARINDEX(@SplitOn,Remainder)-1)
,RIGHT(Remainder,LEN(Remainder)-CHARINDEX(@SplitOn,Remainder))
FROM SplitSting
WHERE Remainder IS NOT NULL AND CHARINDEX(@SplitOn,Remainder)>0
UNION ALL
SELECT
Remainder,null
FROM SplitSting
WHERE Remainder IS NOT NULL AND CHARINDEX(@SplitOn,Remainder)=0
)
SELECT Part FROM SplitSting
)
GO