दिलचस्प पोस्ट
सिस्टम कितनी सटीक है। डायग्नोस्टिक्स। जावास्क्रिप्ट / jQuery के साथ मक्खी पर सीएसएस वर्ग संपत्ति मूल्यों को संशोधित करना एसबीटी में "रन" एक्शन के साथ एक आवेदन चलाने के लिए जेवीएम अधिकतम हेप आकार "-Xmx" कैसे निर्दिष्ट करें? असंगत उद्धरण के साथ सीएसवी फ़ाइल का SQL सर्वर बल्क डालें NSDate से NSDate को समयक्षेत्र के साथ समायोजित करें मानक कंटेनरों की जटिलता की गारंटी क्या है? वर्ग "com.google.firebase.provider.FirebaseInitProvider" नहीं मिला? "मूल संदर्भ" क्या है? बाइट्स की एक स्ट्रिंग को एक int (अजगर) में परिवर्तित करें MySQL SELECT WHERE डेटमैट मैच दिन (और जरूरी नहीं कि समय) क्या मैं मूल चर का नाम पायथन में मुद्रित कर सकता हूं? मैं सीएसएस के साथ एक संपूर्ण वेब पेज कैसे स्केल कर सकता हूं? कैसे <div> टैग को <code> / <pre> टैग में शाब्दिक दिखाना है? UITableView – अनुभाग शीर्षलेख रंग बदलें आप vb.net में HTML को कैसे पार्स करते हैं

मैं एक स्ट्रिंग कैसे विभाजित करूं, ताकि मैं आइटम x एक्सेस कर सकूं?

SQL सर्वर का उपयोग करना, मैं एक स्ट्रिंग कैसे विभाजित करूं, ताकि मैं आइटम x एक्सेस कर सकूं?

एक स्ट्रिंग "हैलो जॉन स्मिथ" लें मैं अंतरिक्ष से स्ट्रिंग को कैसे विभाजित कर सकता हूं और 1 सूचकांक में आइटम को एक्सेस कर सकता हूं, जिसे "जॉन" वापस करना चाहिए?

वेब के समाधान से एकत्रित समाधान "मैं एक स्ट्रिंग कैसे विभाजित करूं, ताकि मैं आइटम x एक्सेस कर सकूं?"

आपको सीडीएल प्रयोक्ता परिभाषित फंक्शन में समाधान मिल सकता है, एक सीमांकित स्ट्रिंग सहायक ( कोड परियोजना से ) पार्स करने के लिए

आप इस सरल तर्क का उपयोग कर सकते हैं:

Declare @products varchar(200) = '1|20|3|343|44|6|8765' Declare @individual varchar(20) = null WHILE LEN(@products) > 0 BEGIN IF PATINDEX('%|%', @products) > 0 BEGIN SET @individual = SUBSTRING(@products, 0, PATINDEX('%|%', @products)) SELECT @individual SET @products = SUBSTRING(@products, LEN(@individual + '|') + 1, LEN(@products)) END ELSE BEGIN SET @individual = @products SET @products = NULL SELECT @individual END END 

मुझे नहीं मानना ​​है कि SQL सर्वर में एक अंतर्निहित विभाजन फ़ंक्शन है, इसलिए यूडीएफ के अलावा, मुझे पता है कि केवल अन्य उत्तर PARSENAME फ़ंक्शन का अपहरण करना है:

 SELECT PARSENAME(REPLACE('Hello John Smith', ' ', '.'), 2) 

PARSENAME एक स्ट्रिंग लेता है और इसे अवधि वर्ण पर विभाजित करता है। इसे अपनी दूसरी तर्क के रूप में एक नंबर लेता है, और वह नंबर निर्दिष्ट करता है कि स्ट्रिंग के किस सेगमेंट को वापस लौटाया जाता है (पीछे से सामने से काम करना)।

 SELECT PARSENAME(REPLACE('Hello John Smith', ' ', '.'), 3) --return Hello 

स्पष्ट समस्या तब होती है जब स्ट्रिंग पहले से ही एक अवधि रखती है। मैं अब भी सोच रहा हूं कि यूडीएफ का सबसे अच्छा तरीका है … कोई और सुझाव?

सबसे पहले, एक फ़ंक्शन बनाएं (सीटीई का प्रयोग करके, सामान्य तालिका अभिव्यक्ति एक अस्थायी तालिका की आवश्यकता से दूर होती है)

  create function dbo.SplitString ( @str nvarchar(4000), @separator char(1) ) returns table AS return ( with tokens(p, a, b) AS ( select 1, 1, charindex(@separator, @str) union all select p + 1, b + 1, charindex(@separator, @str, b + 1) from tokens where b > 0 ) select p-1 zeroBasedOccurance, substring( @str, a, case when b > 0 then ba ELSE 4000 end) AS s from tokens ) GO 

फिर, इसे किसी भी सारणी के रूप में प्रयोग करें (या इसे अपने मौजूदा संग्रहीत proc के भीतर फिट करने के लिए संशोधित करें) जैसे

 select s from dbo.SplitString('Hello John Smith', ' ') where zeroBasedOccurance=1 

अद्यतन करें

पिछला संस्करण 4000 वर्णों से अधिक इनपुट स्ट्रिंग के लिए विफल होगा। यह संस्करण सीमा का ख्याल रखता है:

 create function dbo.SplitString ( @str nvarchar(max), @separator char(1) ) returns table AS return ( with tokens(p, a, b) AS ( select cast(1 as bigint), cast(1 as bigint), charindex(@separator, @str) union all select p + 1, b + 1, charindex(@separator, @str, b + 1) from tokens where b > 0 ) select p-1 ItemIndex, substring( @str, a, case when b > 0 then ba ELSE LEN(@str) end) AS s from tokens ); GO 

उपयोग एक ही रहता है

यहां अधिकांश समाधान लूप या पुनरावर्ती सीटीई के दौरान उपयोग करते हैं। एक सेट-आधारित दृष्टिकोण बेहतर होगा, मैं वादा करता हूँ:

 CREATE FUNCTION [dbo].[SplitString] ( @List NVARCHAR(MAX), @Delim VARCHAR(255) ) RETURNS TABLE AS RETURN ( SELECT [Value] FROM ( SELECT [Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number], CHARINDEX(@Delim, @List + @Delim, [Number]) - [Number]))) FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name) FROM sys.all_objects) AS x WHERE Number <= LEN(@List) AND SUBSTRING(@Delim + @List, [Number], LEN(@Delim)) = @Delim ) AS y ); 

विभाजित कार्यों पर अधिक, क्यों (और सबूत है कि) जबकि loops और पुनरावर्ती सीटीई पैमाने पर नहीं है, और बेहतर विकल्प, अगर बंटवारा स्ट्रिंग अनुप्रयोग परत से आ रही है:

http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings

http://www.sqlperformance.com/2012/08/t-sql-queries/splitting-strings-now-with-less-t-sql

http://sqlblog.com/blogs/aaron_bertrand/archive/2010/07/07/splitting-a-list-of-integers-another-roundup.aspx

स्ट्रिंग पार्सिंग करने के लिए आप एक संख्या तालिका का लाभ उठा सकते हैं।

एक भौतिक संख्या तालिका बनाएं:

  create table dbo.Numbers (N int primary key); insert into dbo.Numbers select top 1000 row_number() over(order by number) from master..spt_values go 

1000000 पंक्तियों के साथ परीक्षण तालिका बनाएं

  create table #yak (i int identity(1,1) primary key, array varchar(50)) insert into #yak(array) select 'a,b,c' from dbo.Numbers n cross join dbo.Numbers nn go 

फ़ंक्शन बनाएं

  create function [dbo].[ufn_ParseArray] ( @Input nvarchar(4000), @Delimiter char(1) = ',', @BaseIdent int ) returns table as return ( select row_number() over (order by n asc) + (@BaseIdent - 1) [i], substring(@Input, n, charindex(@Delimiter, @Input + @Delimiter, n) - n) s from dbo.Numbers where n <= convert(int, len(@Input)) and substring(@Delimiter + @Input, n, 1) = @Delimiter ) go 

उपयोग (मेरे लैपटॉप पर 40 मील में 3 मील पंक्तियाँ आउटपुट करती है)

  select * from #yak cross apply dbo.ufn_ParseArray(array, ',', 1) 

साफ – सफाई

  drop table dbo.Numbers; drop function [dbo].[ufn_ParseArray] 

यहां पर प्रदर्शन अद्भुत नहीं है, लेकिन एक लाख से अधिक पंक्ति तालिका में फ़ंक्शन बुला सर्वोत्तम विचार नहीं है। यदि कई पंक्तियों पर एक स्ट्रिंग विभाजित करते हैं तो मैं फ़ंक्शन से बचता।

यह एक यूडीएफ है जो यह कर देगा। यह सीमांकित मूल्यों की एक तालिका वापस कर देगा, इस पर सभी परिदृश्यों का प्रयास नहीं किया है लेकिन आपका उदाहरण ठीक काम करता है।

 CREATE FUNCTION SplitString ( -- Add the parameters for the function here @myString varchar(500), @deliminator varchar(10) ) RETURNS @ReturnTable TABLE ( -- Add the column definitions for the TABLE variable here [id] [int] IDENTITY(1,1) NOT NULL, [part] [varchar](50) NULL ) AS BEGIN Declare @iSpaces int Declare @part varchar(50) --initialize spaces Select @iSpaces = charindex(@deliminator,@myString,0) While @iSpaces > 0 Begin Select @part = substring(@myString,0,charindex(@deliminator,@myString,0)) Insert Into @ReturnTable(part) Select @part Select @myString = substring(@mystring,charindex(@deliminator,@myString,0)+ len(@deliminator),len(@myString) - charindex(' ',@myString,0)) Select @iSpaces = charindex(@deliminator,@myString,0) end If len(@myString) > 0 Insert Into @ReturnTable Select @myString RETURN END GO 

आप इसे इस तरह कहते हैं:

 Select * From SplitString('Hello John Smith',' ') 

संपादित करें: एक लेन के साथ delimters संभाल करने के लिए अद्यतन समाधान> 1 जैसा में:

 select * From SplitString('Hello**John**Smith','**') 

कोई कोड नहीं है, लेकिन इस पर निश्चित लेख पढ़ें। अन्य उत्तरों में सभी समाधान इस आलेख में सूचीबद्ध लोगों के स्वाद हैं: SQL सर्वर 2005 और परे में एरेज़ और सूचियां

व्यक्तिगत रूप से, मैंने सबसे अधिक संख्या में एक टेबल टेबल समाधान का उपयोग किया है क्योंकि यह उचित है कि मुझे क्या करना है …

यहां मैं समाधान का एक आसान तरीका पोस्ट कर रहा हूं

 CREATE FUNCTION [dbo].[split]( @delimited NVARCHAR(MAX), @delimiter NVARCHAR(100) ) RETURNS @t TABLE (id INT IDENTITY(1,1), val NVARCHAR(MAX)) AS BEGIN DECLARE @xml XML SET @xml = N'<t>' + REPLACE(@delimited,@delimiter,'</t><t>') + '</t>' INSERT INTO @t(val) SELECT r.value('.','varchar(MAX)') as item FROM @xml.nodes('/t') as records(r) RETURN END 

इस तरह से कार्य निष्पादित करें

  select * from dbo.split('Hello John Smith',' ') 

मेरी राय में आप लोग इसे बहुत जटिल बना रहे हैं। बस एक सीएलआर यूडीएफ बनाएं और इसके साथ किया जाए।

 using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; using System.Collections.Generic; public partial class UserDefinedFunctions { [SqlFunction] public static SqlString SearchString(string Search) { List<string> SearchWords = new List<string>(); foreach (string s in Search.Split(new char[] { ' ' })) { if (!s.ToLower().Equals("or") && !s.ToLower().Equals("and")) { SearchWords.Add(s); } } return new SqlString(string.Join(" OR ", SearchWords.ToArray())); } }; 

string और values() स्टेटमेंट का उपयोग करने के बारे में क्या?

 DECLARE @str varchar(max) SET @str = 'Hello John Smith' DECLARE @separator varchar(max) SET @separator = ' ' DECLARE @Splited TABLE(id int IDENTITY(1,1), item varchar(max)) SET @str = REPLACE(@str, @separator, '''),(''') SET @str = 'SELECT * FROM (VALUES(''' + @str + ''')) AS V(A)' INSERT INTO @Splited EXEC(@str) SELECT * FROM @Splited 

परिणाम-निर्धारित प्राप्त

 id item 1 Hello 2 John 3 Smith 

मैं फ़्रैररिक के उत्तर का उपयोग करता हूं लेकिन यह SQL सर्वर 2005 में काम नहीं करता

मैंने इसे संशोधित किया और मैं union all साथ select का उपयोग कर रहा हूं और यह काम करता है

 DECLARE @str varchar(max) SET @str = 'Hello John Smith how are you' DECLARE @separator varchar(max) SET @separator = ' ' DECLARE @Splited table(id int IDENTITY(1,1), item varchar(max)) SET @str = REPLACE(@str, @separator, ''' UNION ALL SELECT ''') SET @str = ' SELECT ''' + @str + ''' ' INSERT INTO @Splited EXEC(@str) SELECT * FROM @Splited 

और परिणाम सेट है:

 id item 1 Hello 2 John 3 Smith 4 how 5 are 6 you 

सवाल स्ट्रिंग विभाजन दृष्टिकोण के बारे में नहीं है , लेकिन एनएथ एलीमेंट कैसे प्राप्त करें

यहां सभी उत्तरों, रिकर्सन, CTE , एकाधिक CHARINDEX , REVERSE और PATINDEX इस्तेमाल करते हुए, सीएलआर विधियों, संख्या तालिकाओं, CROSS APPLY करने के लिए कॉल का उपयोग करते हुए कुछ प्रकार की स्ट्रिंग विभाजन कर रहे हैं … अधिकांश उत्तर कोड के कई लाइनों को कवर करते हैं

लेकिन – यदि आप वास्तव में nth तत्व प्राप्त करने के लिए एक दृष्टिकोण से ज्यादा कुछ नहीं चाहते हैं – यह वास्तविक एक-लाइनर के रूप में किया जा सकता है, कोई यूडीएफ नहीं, यहां तक ​​कि कोई उप-चयन भी नहीं … और एक अतिरिक्त लाभ के रूप में: सुरक्षित टाइप करें

भाग 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 उपयोग करें 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)'); 

यह पैटर्न ठीक काम करता है और आप सामान्यीकरण कर सकते हैं

 Convert(xml,'<n>'+Replace(FIELD,'.','</n><n>')+'</n>').value('(/n[INDEX])','TYPE') ^^^^^ ^^^^^ ^^^^ 

नोट FIELD , INDEX और TYPE

पहचानकर्ताओं के साथ कुछ तालिका जैसे

 sys.message.1234.warning.A45 sys.message.1235.error.O98 .... 

फिर, आप लिख सकते हैं

 SELECT Source = q.value('(/n[1])', 'varchar(10)'), RecordType = q.value('(/n[2])', 'varchar(20)'), RecordNumber = q.value('(/n[3])', 'int'), Status = q.value('(/n[4])', 'varchar(5)') FROM ( SELECT q = Convert(xml,'<n>'+Replace(fieldName,'.','</n><n>')+'</n>') FROM some_TABLE ) Q 

विभाजन और सभी भागों कास्टिंग।

मैं नेट पर समाधान की तलाश कर रहा था और नीचे मेरे लिए काम करता था रेफरी

और आप फ़ंक्शन को इस तरह कॉल करते हैं:

 SELECT * FROM dbo.split('ram shyam hari gopal',' ') 

 SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [dbo].[Split](@String VARCHAR(8000), @Delimiter CHAR(1)) RETURNS @temptable TABLE (items VARCHAR(8000)) AS BEGIN DECLARE @idx INT DECLARE @slice VARCHAR(8000) SELECT @idx = 1 IF len(@String)<1 OR @String IS NULL RETURN WHILE @idx!= 0 BEGIN SET @idx = charindex(@Delimiter,@String) IF @idx!=0 SET @slice = LEFT(@String,@idx - 1) ELSE SET @slice = @String IF(len(@slice)>0) INSERT INTO @temptable(Items) VALUES(@slice) SET @String = RIGHT(@String,len(@String) - @idx) IF len(@String) = 0 break END RETURN END 

फिर भी डेल्मीमीटर फ़ंक्शंस से एक और स्ट्रिंग का हिस्सा मिलता है:

 create function GetStringPartByDelimeter ( @value as nvarchar(max), @delimeter as nvarchar(max), @position as int ) returns NVARCHAR(MAX) AS BEGIN declare @startPos as int declare @endPos as int set @endPos = -1 while (@position > 0 and @endPos != 0) begin set @startPos = @endPos + 1 set @endPos = charindex(@delimeter, @value, @startPos) if(@position = 1) begin if(@endPos = 0) set @endPos = len(@value) + 1 return substring(@value, @startPos, @endPos - @startPos) end set @position = @position - 1 end return null end 

और उपयोग:

 select dbo.GetStringPartByDelimeter ('a;b;c;d;e', ';', 3) 

जो देता है:

 c 

इसे इस्तेमाल करे:

 CREATE function [SplitWordList] ( @list varchar(8000) ) returns @t table ( Word varchar(50) not null, Position int identity(1,1) not null ) as begin declare @pos int, @lpos int, @item varchar(100), @ignore varchar(100), @dl int, @a1 int, @a2 int, @z1 int, @z2 int, @n1 int, @n2 int, @c varchar(1), @a smallint select @a1 = ascii('a'), @a2 = ascii('A'), @z1 = ascii('z'), @z2 = ascii('Z'), @n1 = ascii('0'), @n2 = ascii('9') set @ignore = '''"' set @pos = 1 set @dl = datalength(@list) set @lpos = 1 set @item = '' while (@pos <= @dl) begin set @c = substring(@list, @pos, 1) if (@ignore not like '%' + @c + '%') begin set @a = ascii(@c) if ((@a >= @a1) and (@a <= @z1)) or ((@a >= @a2) and (@a <= @z2)) or ((@a >= @n1) and (@a <= @n2)) begin set @item = @item + @c end else if (@item > '') begin insert into @t values (@item) set @item = '' end end set @pos = @pos + 1 end if (@item > '') begin insert into @t values (@item) end return end 

इसे इस तरह जांचें:

 select * from SplitWordList('Hello John Smith') 

निम्न उदाहरण एक रिकर्सिव सीटीई का उपयोग करता है

18.0 9.2013 को अपडेट करें

 CREATE FUNCTION dbo.SplitStrings_CTE(@List nvarchar(max), @Delimiter nvarchar(1)) RETURNS @returns TABLE (val nvarchar(max), [level] int, PRIMARY KEY CLUSTERED([level])) AS BEGIN ;WITH cte AS ( SELECT SUBSTRING(@List, 0, CHARINDEX(@Delimiter, @List + @Delimiter)) AS val, CAST(STUFF(@List + @Delimiter, 1, CHARINDEX(@Delimiter, @List + @Delimiter), '') AS nvarchar(max)) AS stval, 1 AS [level] UNION ALL SELECT SUBSTRING(stval, 0, CHARINDEX(@Delimiter, stval)), CAST(STUFF(stval, 1, CHARINDEX(@Delimiter, stval), '') AS nvarchar(max)), [level] + 1 FROM cte WHERE stval != '' ) INSERT @returns SELECT REPLACE(val, ' ','' ) AS val, [level] FROM cte WHERE val > '' RETURN END 

SQLFiddle पर डेमो

 Alter Function dbo.fn_Split ( @Expression nvarchar(max), @Delimiter nvarchar(20) = ',', @Qualifier char(1) = Null ) RETURNS @Results TABLE (id int IDENTITY(1,1), value nvarchar(max)) AS BEGIN /* USAGE Select * From dbo.fn_Split('apple pear grape banana orange honeydew cantalope 3 2 1 4', ' ', Null) Select * From dbo.fn_Split('1,abc,"Doe, John",4', ',', '"') Select * From dbo.fn_Split('Hello 0,"&""&&&&', ',', '"') */ -- Declare Variables DECLARE @X xml, @Temp nvarchar(max), @Temp2 nvarchar(max), @Start int, @End int -- HTML Encode @Expression Select @Expression = (Select @Expression For XML Path('')) -- Find all occurences of @Delimiter within @Qualifier and replace with 

***

While PATINDEX('%' + @Qualifier + '%', @Expression) > 0 AND Len(IsNull(@Qualifier, '')) > 0 BEGIN Select — Starting character position of @Qualifier @Start = PATINDEX('%' + @Qualifier + '%', @Expression), — @Expression starting at the @Start position @Temp = SubString(@Expression, @Start + 1, LEN(@Expression)-@Start+1), — Next position of @Qualifier within @Expression @End = PATINDEX('%' + @Qualifier + '%', @Temp) – 1, — The part of Expression found between the @Qualifiers @Temp2 = Case When @End < 0 Then @Temp Else Left(@Temp, @End) End, — New @Expression @Expression = REPLACE(@Expression, @Qualifier + @Temp2 + Case When @End < 0 Then '' Else @Qualifier End, Replace(@Temp2, @Delimiter, '

***

') ) END — Replace all occurences of @Delimiter within @Expression with '</fn_Split>&ltfn_Split>' — And convert it to XML so we can select from it SET @X = Cast('&ltfn_Split>' + Replace(@Expression, @Delimiter, '</fn_Split>&ltfn_Split>') + '</fn_Split>' as xml) — Insert into our returnable table replacing '

***

' back to @Delimiter INSERT @Results SELECT "Value" = LTRIM(RTrim(Replace(C.value('.', 'nvarchar(max)'), '

***

', @Delimiter))) FROM @X.nodes('fn_Split') as X(C) — Return our temp table RETURN END

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मुझे लगता है कि कोई मेरे समाधान से लाभ उठा सकता है।

 select SUBSTRING(column_name,1,CHARINDEX(' ',column_name,1)-1) ,SUBSTRING(SUBSTRING(column_name,CHARINDEX(' ',column_name,1)+1,LEN(column_name)) ,1 ,CHARINDEX(' ',SUBSTRING(column_name,CHARINDEX(' ',column_name,1)+1,LEN(column_name)),1)-1) ,SUBSTRING(SUBSTRING(column_name,CHARINDEX(' ',column_name,1)+1,LEN(column_name)) ,CHARINDEX(' ',SUBSTRING(column_name,CHARINDEX(' ',column_name,1)+1,LEN(column_name)),1)+1 ,LEN(column_name)) from table_name 

एसक्यूएल FIDDLE

लाभ:

  • यह '3' द्वारा सभी 3 उप-स्ट्रिंग्स डेलीमिनेटर को अलग करती है।
  • लूप के दौरान किसी का उपयोग नहीं करना चाहिए, क्योंकि यह प्रदर्शन कम करता है
  • पिवट के लिए कोई ज़रूरत नहीं है क्योंकि सभी परिणामस्वरूप उप-स्ट्रिंग एक पंक्ति में प्रदर्शित की जाएगी

सीमाएं:

  • किसी को कुल संख्या पता होना चाहिए रिक्त स्थान (उप-स्ट्रिंग) का

नोट : समाधान उप-स्ट्रिंग को एन को दे सकता है

सीमा को पार करने के लिए हम निम्न रेफरी का उपयोग कर सकते हैं

लेकिन फिर से ऊपर के समाधान का उपयोग किसी तालिका में नहीं किया जा सकता (Actaully मैं इसका उपयोग करने में सक्षम नहीं था)।

फिर मुझे उम्मीद है कि यह समाधान कुछ-एक की मदद कर सकता है

अपडेट: रिकॉर्ड्स के मामले में> 50000 LOOPS का उपयोग करने के लिए उचित नहीं है क्योंकि यह प्रदर्शन को नीचा जाएगा

लगभग सभी अन्य उत्तरों विभाजन कोड स्ट्रिंग को विभाजित कर रहे हैं जो CPU चक्र को बर्बाद कर देता है और अनावश्यक स्मृति आवंटन करता है।

स्ट्रिंग स्प्लिट करने के लिए मैं एक बेहतर तरीके को कवर करता हूं: http://www.digitalruby.com/split-string-sql-server/

यहां कोड है:

 SET NOCOUNT ON -- You will want to change nvarchar(MAX) to nvarchar(50), varchar(50) or whatever matches exactly with the string column you will be searching against DECLARE @SplitStringTable TABLE (Value nvarchar(MAX) NOT NULL) DECLARE @StringToSplit nvarchar(MAX) = 'your|string|to|split|here' DECLARE @SplitEndPos int DECLARE @SplitValue nvarchar(MAX) DECLARE @SplitDelim nvarchar(1) = '|' DECLARE @SplitStartPos int = 1 SET @SplitEndPos = CHARINDEX(@SplitDelim, @StringToSplit, @SplitStartPos) WHILE @SplitEndPos > 0 BEGIN SET @SplitValue = SUBSTRING(@StringToSplit, @SplitStartPos, (@SplitEndPos - @SplitStartPos)) INSERT @SplitStringTable (Value) VALUES (@SplitValue) SET @SplitStartPos = @SplitEndPos + 1 SET @SplitEndPos = CHARINDEX(@SplitDelim, @StringToSplit, @SplitStartPos) END SET @SplitValue = SUBSTRING(@StringToSplit, @SplitStartPos, 2147483647) INSERT @SplitStringTable (Value) VALUES(@SplitValue) SET NOCOUNT OFF -- You can select or join with the values in @SplitStringTable at this point. 

पुनरावर्ती CTE साथ TVF का उपयोग करके शुद्ध सेट-आधारित समाधान। आप इस फ़ंक्शन को किसी भी डाटासेट पर शामिल कर सकते हैं और APPLY कर सकते हैं।

 create function [dbo].[SplitStringToResultSet] (@value varchar(max), @separator char(1)) returns table as return with r as ( select value, cast(null as varchar(max)) [x], -1 [no] from (select rtrim(cast(@value as varchar(max))) [value]) as j union all select right(value, len(value)-case charindex(@separator, value) when 0 then len(value) else charindex(@separator, value) end) [value] , left(r.[value], case charindex(@separator, r.value) when 0 then len(r.value) else abs(charindex(@separator, r.[value])-1) end ) [x] , [no] + 1 [no] from r where value > '') select ltrim(x) [value], [no] [index] from r where x is not null; go 

उपयोग:

 select * from [dbo].[SplitStringToResultSet]('Hello John Smith', ' ') where [index] = 1; 

परिणाम:

 value index ------------- John 1 

फ़ंक्शन की आवश्यकता के बिना आप SQL में एक स्ट्रिंग विभाजित कर सकते हैं:

 DECLARE @bla varchar(MAX) SET @bla = 'BED40DFC-F468-46DD-8017-00EF2FA3E4A4,64B59FC5-3F4D-4B0E-9A48-01F3D4F220B0,A611A108-97CA-42F3-A2E1-057165339719,E72D95EA-578F-45FC-88E5-075F66FD726C' -- http://stackoverflow.com/questions/14712864/how-to-query-values-from-xml-nodes SELECT x.XmlCol.value('.', 'varchar(36)') AS val FROM ( SELECT CAST('<e>' + REPLACE(@bla, ',', '</e><e>') + '</e>' AS xml) AS RawXml ) AS b CROSS APPLY b.RawXml.nodes('e') x(XmlCol); 

यदि आपको मनमानी स्ट्रिंग्स का समर्थन करने की आवश्यकता है (xml विशेष अक्षर के साथ)

 DECLARE @bla NVARCHAR(MAX) SET @bla = '<html>unsafe & safe Utf8CharsDon''tGetEncoded ÄöÜ - "Conex"<html>,Barnes & Noble,abc,def,ghi' -- http://stackoverflow.com/questions/14712864/how-to-query-values-from-xml-nodes SELECT x.XmlCol.value('.', 'nvarchar(MAX)') AS val FROM ( SELECT CAST('<e>' + REPLACE((SELECT @bla FOR XML PATH('')), ',', '</e><e>') + '</e>' AS xml) AS RawXml ) AS b CROSS APPLY b.RawXml.nodes('e') x(XmlCol); 

SQL Server 2016 के साथ शुरू हम string_split

 DECLARE @string varchar(100) = 'Richard, Mike, Mark' SELECT value FROM string_split(@string, ',') 

खैर, मेरा वह सब आसान नहीं है, लेकिन यहां कोड है जिसे मैं अल्पविराम-सीमांकित इनपुट वैरिएबल को अलग-अलग मानों में विभाजित करने के लिए उपयोग करता हूं, और इसे एक टेबल वैरिएबल में डाल दिया। मुझे यकीन है कि आप इस स्थान को एक स्थान पर विभाजित करने के लिए थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-थोड़ी-

 -- Create temporary table to parse the list of accounting cycles. DECLARE @tblAccountingCycles table ( AccountingCycle varchar(10) ) DECLARE @vchAccountingCycle varchar(10) DECLARE @intPosition int SET @vchAccountingCycleIDs = LTRIM(RTRIM(@vchAccountingCycleIDs)) + ',' SET @intPosition = CHARINDEX(',', @vchAccountingCycleIDs, 1) IF REPLACE(@vchAccountingCycleIDs, ',', '') <> '' BEGIN WHILE @intPosition > 0 BEGIN SET @vchAccountingCycle = LTRIM(RTRIM(LEFT(@vchAccountingCycleIDs, @intPosition - 1))) IF @vchAccountingCycle <> '' BEGIN INSERT INTO @tblAccountingCycles (AccountingCycle) VALUES (@vchAccountingCycle) END SET @vchAccountingCycleIDs = RIGHT(@vchAccountingCycleIDs, LEN(@vchAccountingCycleIDs) - @intPosition) SET @intPosition = CHARINDEX(',', @vchAccountingCycleIDs, 1) END END 

अवधारणा बहुत ही समान है एक अन्य विकल्प एसक्यूएल सर्वर 2005 के भीतर ही नेट संगतता का लाभ उठाना है। आप अनिवार्य रूप से अपने आप को एक सरल तरीका लिख ​​सकते हैं जो .NET में स्ट्रिंग को विभाजित करेगा और फिर एक संग्रहीत कार्यविधि / फ़ंक्शन के रूप में प्रदर्शित करेगा।

This is something I did in order to get a specific token in a string. (Tested in MSSQL 2008)

First, creating the following functions: (found in: here

 CREATE FUNCTION dbo.SplitStrings_Moden ( @List NVARCHAR(MAX), @Delimiter NVARCHAR(255) ) RETURNS TABLE WITH SCHEMABINDING AS RETURN WITH E1(N) AS ( SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1), E2(N) AS (SELECT 1 FROM E1 a, E1 b), E4(N) AS (SELECT 1 FROM E2 a, E2 b), E42(N) AS (SELECT 1 FROM E4 a, E2 b), cteTally(N) AS (SELECT 0 UNION ALL SELECT TOP (DATALENGTH(ISNULL(@List,1))) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E42), cteStart(N1) AS (SELECT t.N+1 FROM cteTally t WHERE (SUBSTRING(@List,tN,1) = @Delimiter OR tN = 0)) SELECT Item = SUBSTRING(@List, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@List,s.N1),0)-s.N1,8000)) FROM cteStart s; 

तथा

 create FUNCTION dbo.getToken ( @List NVARCHAR(MAX), @Delimiter NVARCHAR(255), @Pos int ) RETURNS varchar(max) as begin declare @returnValue varchar(max); select @returnValue = tbl.Item from ( select ROW_NUMBER() over (order by (select null)) as id, * from dbo.SplitStrings_Moden(@List, @Delimiter) ) as tbl where tbl.id = @Pos return @returnValue end 

then you can use it like that:

 select dbo.getToken('1111_2222_3333_', '_', 1) 

which return 1111

Recursive CTE solution with server pain, test it

MS SQL Server 2008 Schema Setup :

 create table Course( Courses varchar(100) ); insert into Course values ('Hello John Smith'); 

Query 1 :

 with cte as ( select left( Courses, charindex( ' ' , Courses) ) as a_l, cast( substring( Courses, charindex( ' ' , Courses) + 1 , len(Courses ) ) + ' ' as varchar(100) ) as a_r, Courses as a, 0 as n from Course t union all select left(a_r, charindex( ' ' , a_r) ) as a_l, substring( a_r, charindex( ' ' , a_r) + 1 , len(a_R ) ) as a_r, cte.a, cte.n + 1 as n from Course t inner join cte on t.Courses = cte.a and len( a_r ) > 0 ) select a_l, n from cte --where N = 1 

Results :

 | A_L | N | |--------|---| | Hello | 0 | | John | 1 | | Smith | 2 | 

while similar to the xml based answer by josejuan, i found that processing the xml path only once, then pivoting was moderately more efficient:

 select ID, [3] as PathProvidingID, [4] as PathProvider, [5] as ComponentProvidingID, [6] as ComponentProviding, [7] as InputRecievingID, [8] as InputRecieving, [9] as RowsPassed, [10] as InputRecieving2 from ( select id,message,d.* from sysssislog cross apply ( SELECT Item = yivalue('(./text())[1]', 'varchar(200)'), row_number() over(order by yi) as rn FROM ( SELECT x = CONVERT(XML, '<i>' + REPLACE(Message, ':', '</i><i>') + '</i>').query('.') ) AS a CROSS APPLY x.nodes('i') AS y(i) ) d WHERE event = 'OnPipelineRowsSent' ) as tokens pivot ( max(item) for [rn] in ([3],[4],[5],[6],[7],[8],[9],[10]) ) as data 

ran in 8:30

 select id, tokens.value('(/n[3])', 'varchar(100)')as PathProvidingID, tokens.value('(/n[4])', 'varchar(100)') as PathProvider, tokens.value('(/n[5])', 'varchar(100)') as ComponentProvidingID, tokens.value('(/n[6])', 'varchar(100)') as ComponentProviding, tokens.value('(/n[7])', 'varchar(100)') as InputRecievingID, tokens.value('(/n[8])', 'varchar(100)') as InputRecieving, tokens.value('(/n[9])', 'varchar(100)') as RowsPassed from ( select id, Convert(xml,'<n>'+Replace(message,'.','</n><n>')+'</n>') tokens from sysssislog WHERE event = 'OnPipelineRowsSent' ) as data 

ran in 9:20

 CREATE FUNCTION [dbo].[fnSplitString] ( @string NVARCHAR(MAX), @delimiter CHAR(1) ) RETURNS @output TABLE(splitdata NVARCHAR(MAX) ) BEGIN DECLARE @start INT, @end INT SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) WHILE @start < LEN(@string) + 1 BEGIN IF @end = 0 SET @end = LEN(@string) + 1 INSERT INTO @output (splitdata) VALUES(SUBSTRING(@string, @start, @end - @start)) SET @start = @end + 1 SET @end = CHARINDEX(@delimiter, @string, @start) END RETURN END 

AND USE IT

 select *from dbo.fnSplitString('Querying SQL Server','') 

if anyone wants to get only one part of the seperatured text can use this

select * from fromSplitStringSep('Word1 wordr2 word3',' ')

 CREATE function [dbo].[SplitStringSep] ( @str nvarchar(4000), @separator char(1) ) returns table AS return ( with tokens(p, a, b) AS ( select 1, 1, charindex(@separator, @str) union all select p + 1, b + 1, charindex(@separator, @str, b + 1) from tokens where b > 0 ) select p-1 zeroBasedOccurance, substring( @str, a, case when b > 0 then ba ELSE 4000 end) AS s from tokens ) 

I devoloped this,

 declare @x nvarchar(Max) = 'ali.veli.deli.'; declare @item nvarchar(Max); declare @splitter char='.'; while CHARINDEX(@splitter,@x) != 0 begin set @item = LEFT(@x,CHARINDEX(@splitter,@x)) set @x = RIGHT(@x,len(@x)-len(@item) ) select @item as item, @x as x; end 

the only attention you should is dot '.' that end of the @x is always should be there.