यह प्रश्न एक स्ट्रिंग विभाजन दृष्टिकोण के बारे में नहीं है , लेकिन एनटीएच तत्व को कैसे प्राप्त किया जाए , इसके बारे में ।
यहां सभी उत्तर पुनरावृत्ति, CTEएस, मल्टीपल CHARINDEX, REVERSEऔर PATINDEX, आविष्कार कार्यों का उपयोग करते हुए, सीएलआर विधियों के लिए कॉल, नंबर टेबल, CROSS APPLYएस ... के कुछ प्रकार के स्ट्रिंग विभाजन कर रहे हैं ... अधिकांश उत्तर कोड की कई लाइनों को कवर करते हैं।
लेकिन - अगर आप वास्तव में nth तत्व प्राप्त करने के लिए एक दृष्टिकोण से ज्यादा कुछ नहीं चाहते हैं - तो इसे वास्तविक वन-लाइनर के रूप में किया जा सकता है , कोई UDF नहीं, एक उप-चयन भी नहीं ... और अतिरिक्त लाभ के रूप में: सुरक्षित लिखें
भाग 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: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)')
यदि आपका तार शामिल हो सकता है निषिद्ध वर्ण (विशेष रूप से एक के बीच &><) , तो आप अभी भी इसे इस तरह से कर सकते हैं। बस 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है वास्तव में तेजी से। यहां तक कि प्रसिद्ध "सीमांकित सीप्लेट 8k ()" विधि की तुलना में बहुत तेज ...
अद्यतन 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