यह प्रश्न एक स्ट्रिंग विभाजन दृष्टिकोण के बारे में नहीं है , लेकिन एनटीएच तत्व को कैसे प्राप्त किया जाए , इसके बारे में ।
यहां सभी उत्तर पुनरावृत्ति, 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