67 (टाइप-सेफ !! . को पुनः प्राप्त करने का यह सबसे आसान उत्तर है ):
SELECT CAST('<x>' + REPLACE('1,222,2,67,888,1111',',','</x><x>') + '</x>' AS XML).value('/x[4]','int')
निम्नलिखित में आपको उदाहरण मिलेंगे कि स्ट्रिंग, सीमांकक और स्थिति के लिए चर के साथ इसका उपयोग कैसे करें (यहां तक कि एक्सएमएल-निषिद्ध वर्णों वाले किनारे-मामलों के लिए भी)
आसान
यह प्रश्न स्ट्रिंग स्प्लिट दृष्टिकोण के बारे में नहीं है , लेकिन nth तत्व कैसे प्राप्त करें . के बारे में . सबसे आसान, पूरी तरह से इनलाइन करने योग्य तरीका यह IMO होगा:
यह एक असली वन-लाइनर है भाग 2 को एक स्थान से सीमांकित करने के लिए:
DECLARE @input NVARCHAR(100)=N'part1 part2 part3';
SELECT CAST(N'<x>' + REPLACE(@input,N' ',N'</x><x>') + N'</x>' AS XML).value('/x[2]','nvarchar(max)')
चर का उपयोग sql:variable()
के साथ किया जा सकता है या sql:column()
बेशक आप चर का उपयोग कर सकते हैं सीमांकक और स्थिति के लिए (sql:column
. का उपयोग करें) किसी क्वेरी के मान से सीधे स्थिति प्राप्त करने के लिए):
DECLARE @dlmt NVARCHAR(10)=N' ';
DECLARE @pos INT = 2;
SELECT CAST(N'<x>' + REPLACE(@input,@dlmt,N'</x><x>') + N'</x>' AS XML).value('/x[sql:variable("@pos")][1]','nvarchar(max)')
एज-केस XML-वर्जित वर्णों के साथ
यदि आपकी स्ट्रिंग में निषिद्ध वर्ण शामिल हो सकते हैं , आप अभी भी इसे इस तरह से कर सकते हैं। बस FOR XML PATH
का उपयोग करें अपने स्ट्रिंग पर पहले सभी निषिद्ध वर्णों को फिटिंग एस्केप अनुक्रम के साथ परोक्ष रूप से प्रतिस्थापित करने के लिए।
यह एक बहुत ही विशेष मामला है यदि - इसके अतिरिक्त - आपका सीमांकक अर्धविराम है . इस मामले में मैं पहले सीमांकक को '#DLMT#' से बदल देता हूं, और अंत में इसे XML टैग से बदल देता हूं:
SET @input=N'Some <, > and &;Other äöü@€;One more';
SET @dlmt=N';';
SELECT CAST(N'<x>' + REPLACE((SELECT REPLACE(@input,@dlmt,'#DLMT#') AS [*] FOR XML PATH('')),N'#DLMT#',N'</x><x>') + N'</x>' AS XML).value('/x[sql:variable("@pos")][1]','nvarchar(max)');
SQL-सर्वर 2016+ के लिए अद्यतन
खेद है कि डेवलपर्स STRING_SPLIT
. के साथ भाग की अनुक्रमणिका वापस करना भूल गए . लेकिन, SQL-सर्वर 2016+ का उपयोग करते हुए, JSON_VALUE
. है और OPENJSON
।
JSON_VALUE
. के साथ हम स्थिति में इंडेक्स 'एरे के रूप में पास कर सकते हैं।
OPENJSON
के लिए दस्तावेज़ीकरण स्पष्ट रूप से बताता है:
जब OPENJSON किसी JSON सरणी को पार्स करता है, तो फ़ंक्शन JSON टेक्स्ट में तत्वों की अनुक्रमणिका को कुंजियों के रूप में लौटाता है।
एक स्ट्रिंग जैसे 1,2,3
कोष्ठक के अलावा और कुछ नहीं चाहिए:[1,2,3]
.
शब्दों की एक स्ट्रिंग जैसे this is an example
["this","is","an"," example"]
. होना चाहिए .
ये बहुत आसान स्ट्रिंग ऑपरेशन हैं। बस इसे आज़माएं:
DECLARE @str VARCHAR(100)='Hello John Smith';
DECLARE @position INT = 2;
--We can build the json-path '$[1]' using CONCAT
SELECT JSON_VALUE('["' + REPLACE(@str,' ','","') + '"]',CONCAT('$[',@position-1,']'));
-- इसे सुरक्षित स्ट्रिंग-स्प्लिटर की स्थिति के लिए देखें (शून्य-आधारित ):
SELECT JsonArray.[key] AS [Position]
,JsonArray.[value] AS [Part]
FROM OPENJSON('["' + REPLACE(@str,' ','","') + '"]') JsonArray
इस पोस्ट में मैंने विभिन्न तरीकों का परीक्षण किया और पाया कि OPENJSON
वास्तव में तेज़ है। प्रसिद्ध "delimitedSplit8k ()" विधि से भी बहुत तेज...
अपडेट 2 - टाइप-सुरक्षित मान प्राप्त करें
हम सरणी के भीतर सरणी का उपयोग कर सकते हैं केवल दोगुने [[]]
. का उपयोग करके . यह टाइप किए गए WITH
. की अनुमति देता है -क्लॉज:
DECLARE @SomeDelimitedString VARCHAR(100)='part1|1|20190920';
DECLARE @JsonArray NVARCHAR(MAX)=CONCAT('[["',REPLACE(@SomeDelimitedString,'|','","'),'"]]');
SELECT @SomeDelimitedString AS TheOriginal
,@JsonArray AS TransformedToJSON
,ValuesFromTheArray.*
FROM OPENJSON(@JsonArray)
WITH(TheFirstFragment VARCHAR(100) '$[0]'
,TheSecondFragment INT '$[1]'
,TheThirdFragment DATE '$[2]') ValuesFromTheArray