কমা দ্বারা পৃথক করা স্ট্রিংকে পৃথক সারিতে রূপান্তর করা


234

আমার মতো এসকিউএল টেবিল রয়েছে:

| SomeID         | OtherID     | Data
+----------------+-------------+-------------------
| abcdef-.....   | cdef123-... | 18,20,22
| abcdef-.....   | 4554a24-... | 17,19
| 987654-.....   | 12324a2-... | 13,19,20

এখানে এমন একটি ক্যোয়ারী রয়েছে যেখানে আমি SELECT OtherID, SplitData WHERE SomeID = 'abcdef-.......'পৃথক সারিগুলি ফেরত দেওয়ার মতো একটি ক্যোয়ারী সম্পাদন করতে পারি :

| OtherID     | SplitData
+-------------+-------------------
| cdef123-... | 18
| cdef123-... | 20
| cdef123-... | 22
| 4554a24-... | 17
| 4554a24-... | 19

মূলত কমাতে আমার ডেটা পৃথক সারিতে বিভক্ত করবেন?

আমি সচেতন যে comma-separatedএকটি সম্পর্কযুক্ত ডাটাবেসের মধ্যে একটি স্ট্রিং সংরক্ষণ বোবা শোনায়, কিন্তু ভোক্তা অ্যাপ্লিকেশন সাধারণ ব্যবহারের ক্ষেত্রে যে সত্যই সহায়ক।

আমার পেজিং দরকার হওয়ায় আমি অ্যাপ্লিকেশনটিতে বিভাজন করতে চাই না, তাই আমি পুরো অ্যাপ্লিকেশনটিকে রিফ্যাক্টর করার আগে বিকল্পগুলি অন্বেষণ করতে চেয়েছিলাম।

এটি SQL Server 2008(নন-আর 2)।


উত্তর:


265

আপনি এসকিউএল সার্ভার থেকে দুর্দান্ত পুনরাবৃত্ত ফাংশন ব্যবহার করতে পারেন:


নমুনা সারণী:

CREATE TABLE Testdata
(
    SomeID INT,
    OtherID INT,
    String VARCHAR(MAX)
)

INSERT Testdata SELECT 1,  9, '18,20,22'
INSERT Testdata SELECT 2,  8, '17,19'
INSERT Testdata SELECT 3,  7, '13,19,20'
INSERT Testdata SELECT 4,  6, ''
INSERT Testdata SELECT 9, 11, '1,2,3,4'

ক্যোয়ারী

;WITH tmp(SomeID, OtherID, DataItem, String) AS
(
    SELECT
        SomeID,
        OtherID,
        LEFT(String, CHARINDEX(',', String + ',') - 1),
        STUFF(String, 1, CHARINDEX(',', String + ','), '')
    FROM Testdata
    UNION all

    SELECT
        SomeID,
        OtherID,
        LEFT(String, CHARINDEX(',', String + ',') - 1),
        STUFF(String, 1, CHARINDEX(',', String + ','), '')
    FROM tmp
    WHERE
        String > ''
)

SELECT
    SomeID,
    OtherID,
    DataItem
FROM tmp
ORDER BY SomeID
-- OPTION (maxrecursion 0)
-- normally recursion is limited to 100. If you know you have very long
-- strings, uncomment the option

আউটপুট

 SomeID | OtherID | DataItem 
--------+---------+----------
 1      | 9       | 18       
 1      | 9       | 20       
 1      | 9       | 22       
 2      | 8       | 17       
 2      | 8       | 19       
 3      | 7       | 13       
 3      | 7       | 19       
 3      | 7       | 20       
 4      | 6       |          
 9      | 11      | 1        
 9      | 11      | 2        
 9      | 11      | 3        
 9      | 11      | 4        

1
কোড কাজ করে না যদি পরিবর্তন কলামের ডাটা টাইপ Dataথেকে varchar(max)থেকে varchar(4000), যেমন create table Testdata(SomeID int, OtherID int, Data varchar(4000))?
ca9163d9

4
@ নিক ডব্লু এটি হতে পারে কারণ ইউনিয়ন সমস্তের আগে এবং পরে অংশগুলি বাম ফাংশন থেকে বিভিন্ন ধরণের ফিরে আসে। ব্যক্তিগতভাবে আমি দেখতে পাচ্ছি না কেন একবার আপনি 4000 এ
উঠলে

একটি বড় মানের মানগুলির জন্য, এটি সিটিইগুলির জন্য পুনরাবৃত্তি সীমা অতিক্রম করতে পারে।
ডিএসজি

3
@dz আপনি যখন ব্যবহার করবেনOPTION (maxrecursion 0)
রিচার্ডকিউই

14
লেফট ফাংশনগুলিতে কাজ করার জন্য একটি ক্যাসেটের প্রয়োজন হতে পারে .... উদাহরণস্বরূপ
লেফট

141

অবশেষে, এসকিউএল সার্ভার 2016 এর সাথে অপেক্ষা শেষ । তারা স্প্লিট স্ট্রিং ফাংশন চালু করেছে,STRING_SPLIT :

select OtherID, cs.Value --SplitData
from yourtable
cross apply STRING_SPLIT (Data, ',') cs

এক্সএমএল, ট্যালি টেবিলের মতো স্ট্র্যাপকে বিভক্ত করার অন্যান্য সমস্ত পদ্ধতি, লুপ ইত্যাদির মাধ্যমে এটিকে উড়িয়ে দেওয়া হয়েছে STRING_SPLIT ফাংশনটি ।

এখানে পারফরম্যান্স তুলনা সহ একটি দুর্দান্ত নিবন্ধ: পারফরম্যান্স আশ্চর্য এবং অনুমান: STRING_SPLIT

পুরানো সংস্করণগুলির জন্য, ট্যালি টেবিল ব্যবহার করে এখানে বিভক্ত স্ট্রিং ফাংশন (সম্ভাব্য সর্বোত্তম পদ্ধতি)

CREATE FUNCTION [dbo].[DelimitedSplit8K]
        (@pString VARCHAR(8000), @pDelimiter CHAR(1))
RETURNS TABLE WITH SCHEMABINDING AS
 RETURN
--===== "Inline" CTE Driven "Tally Table" produces values from 0 up to 10,000...
     -- enough to cover NVARCHAR(4000)
  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
                ),                          --10E+1 or 10 rows
       E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
       E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
 cteTally(N) AS (--==== This provides the "base" CTE and limits the number of rows right up front
                     -- for both a performance gain and prevention of accidental "overruns"
                 SELECT TOP (ISNULL(DATALENGTH(@pString),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
                ),
cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter)
                 SELECT 1 UNION ALL
                 SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString,t.N,1) = @pDelimiter
                ),
cteLen(N1,L1) AS(--==== Return start and length (for use in substring)
                 SELECT s.N1,
                        ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,s.N1),0)-s.N1,8000)
                   FROM cteStart s
                )
--===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found.
 SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
        Item       = SUBSTRING(@pString, l.N1, l.L1)
   FROM cteLen l
;

থেকে রেফার করা ট্যালি ওহ রেফারেন্স! একটি উন্নত এসকিউএল 8 কে "সিএসভি বিভাজন" ফাংশন


9
খুব গুরুত্বপূর্ণ উত্তর
সৈয়দ মোঃ কামরুজ্জামান

কেবলমাত্র সার্ভারটি এসকিউএল সার্ভারে থাকলে আমি STRING_SPLIT ব্যবহার করব! বিটিডাব্লু আপনি যে পৃষ্ঠায় লিঙ্ক করেছেন তার অনুসারে, ক্ষেত্রের নামটি আউটপুট দেয় value, তা নয় SplitData
স্টিয়ার্ট

89

এটা যাচাই কর

 SELECT A.OtherID,  
     Split.a.value('.', 'VARCHAR(100)') AS Data  
 FROM  
 (
     SELECT OtherID,  
         CAST ('<M>' + REPLACE(Data, ',', '</M><M>') + '</M>' AS XML) AS Data  
     FROM  Table1
 ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a); 

8
এই পদ্ধতির ব্যবহার করার সময় আপনাকে অবশ্যই নিশ্চিত করতে হবে যে আপনার মানগুলির মধ্যে
কোনওটিতেই

এটা অসাধারণ. আমি কি আপনাকে জিজ্ঞাসা করতে পারি, আমি কীভাবে নতুন করে লিখব যে আমি যদি নতুন কলামটি কেবল আমার বিভক্ত স্ট্রিং থেকে প্রথম চরিত্রটি প্রদর্শন করতে চাই?
নিয়ন্ত্রণ করুন

এটি নিখুঁতভাবে কাজ করেছে, আপনাকে ধন্যবাদ! আমাকে ভিআচআরএআর সীমাটি আপডেট করতে হয়েছিল তবে এটির পরে এটি পুরোপুরি কার্যকর হয়েছিল।
chazbot7

আমাকে আপনাকে বলতে হবে যে পদ্ধতিটি "প্রেমময়" (ভালোবাসার অনুভূতি?) "এক্সএমএল স্প্লিটটার পদ্ধতি" নামে পরিচিত এবং এটি লুপ বা রিকার্সিভ সিটিইর মতো প্রায় ধীরে ধীরে। আমি দৃ strongly়ভাবে পরামর্শ দিচ্ছি যে আপনি এটি সর্বদা এড়ানো উচিত। পরিবর্তে ডিলিমিটেডস্প্লিট 8 কে ব্যবহার করুন। এটি 2016 এর স্প্লিট_সার্টিং () ফাংশন বা একটি ভাল লিখিত সিএলআর বাদে সমস্ত কিছুর দরজা বন্ধ করে দেয়।
জেফ মোডেন

20
select t.OtherID,x.Kod
    from testData t
    cross apply (select Code from dbo.Split(t.Data,',') ) x

3
আমি পরে যা করেছি ঠিক তেমনটি করে এবং অন্যান্য উদাহরণগুলির তুলনায় আরও সহজে পড়া সহজ হয় (তবে আগেই ডিবিতে সীমিত স্ট্রিং বিভক্তির জন্য একটি কার্যকারিতা রয়েছে)। যেহেতু আগে কেউ পরিচিত ছিল না, তেমনি CROSS APPLYএটি দরকারী!
tobriand

আমি এই অংশটি বুঝতে পারি না (dbo.Split (t.Data, ',') থেকে কোড নির্বাচন করুন)? dbo.Split একটি টেবিল যেখানে এটি বিদ্যমান এবং এছাড়াও কোডটি স্প্লিট টেবিলের কলাম আছে? আমি এই পৃষ্ঠার কোথাও সেই টেবিল বা মানগুলির তালিকাটি পাই না?
জয়েন্দ্রন

1
আমার কাজের কোডটি select t.OtherID, x.* from testData t cross apply (select item as Data from dbo.Split(t.Data,',') ) x
হ'ল

12

ফেব্রুয়ারী ২০১ 2016 পর্যন্ত - টেবিলের টেবিলের উদাহরণটি দেখুন - খুব সম্ভবত আমার ফেব্রুয়ারী ২০১৪ থেকে নীচে আমার টিভিএফকে ছাড়িয়ে যাওয়ার সম্ভাবনা রয়েছে ter


উপরের উদাহরণগুলিতে আমার পছন্দ অনুসারে প্রচুর পুনরাবৃত্তি কোড। এবং আমি সিটিই এবং এক্সএমএলের অভিনয় অপছন্দ করি। এছাড়াও, একটি স্পষ্টত Idযাতে গ্রাহকরা যাতে নির্দিষ্ট অর্ডার দেয় তারা একটি ORDER BYদফা নির্দিষ্ট করতে পারে ।

CREATE FUNCTION dbo.Split
(
    @Line nvarchar(MAX),
    @SplitOn nvarchar(5) = ','
)
RETURNS @RtnValue table
(
    Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED,
    Data nvarchar(100) NOT NULL
)
AS
BEGIN
    IF @Line IS NULL RETURN

    DECLARE @split_on_len INT = LEN(@SplitOn)
    DECLARE @start_at INT = 1
    DECLARE @end_at INT
    DECLARE @data_len INT

    WHILE 1=1
    BEGIN
        SET @end_at = CHARINDEX(@SplitOn,@Line,@start_at)
        SET @data_len = CASE @end_at WHEN 0 THEN LEN(@Line) ELSE @end_at-@start_at END
        INSERT INTO @RtnValue (data) VALUES( SUBSTRING(@Line,@start_at,@data_len) );
        IF @end_at = 0 BREAK;
        SET @start_at = @end_at + @split_on_len
    END

    RETURN
END

6

এটি 2016 এর সংস্করণে সমাধান করা হয়েছে দেখে ভাল লাগল, তবে এটির মধ্যে নেই এমন সবার জন্য এখানে উপরের পদ্ধতির দুটি সাধারণকরণ এবং সরলিকৃত সংস্করণ দেওয়া আছে।

এক্সএমএল-পদ্ধতিটি ছোট, তবে অবশ্যই এক্সএমএল-ট্রিকের জন্য স্ট্রিংটির প্রয়োজন (কোনও 'খারাপ' অক্ষর নয়))

এক্সএমএল-পদ্ধতি:

create function dbo.splitString(@input Varchar(max), @Splitter VarChar(99)) returns table as
Return
    SELECT Split.a.value('.', 'VARCHAR(max)') AS Data FROM
    ( SELECT CAST ('<M>' + REPLACE(@input, @Splitter, '</M><M>') + '</M>' AS XML) AS Data 
    ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a); 

পুনরাবৃত্তির পদ্ধতি:

create function dbo.splitString(@input Varchar(max), @Splitter Varchar(99)) returns table as
Return
  with tmp (DataItem, ix) as
   ( select @input  , CHARINDEX('',@Input)  --Recu. start, ignored val to get the types right
     union all
     select Substring(@input, ix+1,ix2-ix-1), ix2
     from (Select *, CHARINDEX(@Splitter,@Input+@Splitter,ix+1) ix2 from tmp) x where ix2<>0
   ) select DataItem from tmp where ix<>0

ক্রিয়াকলাপ

Create table TEST_X (A int, CSV Varchar(100));
Insert into test_x select 1, 'A,B';
Insert into test_x select 2, 'C,D';

Select A,data from TEST_X x cross apply dbo.splitString(x.CSV,',') Y;

Drop table TEST_X

এক্সএমএল-পদ্ধতি 2: ইউনিকোড বন্ধুত্বপূর্ণ 😀 (ম্যাক্স হজস সংযোজন সৌজন্যে) create function dbo.splitString(@input nVarchar(max), @Splitter nVarchar(99)) returns table as Return SELECT Split.a.value('.', 'NVARCHAR(max)') AS Data FROM ( SELECT CAST ('<M>' + REPLACE(@input, @Splitter, '</M><M>') + '</M>' AS XML) AS Data ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a);


1
এটি সুস্পষ্ট বলে মনে হতে পারে তবে আপনি এই দুটি ফাংশন কীভাবে ব্যবহার করবেন? বিশেষত, আপনি কীভাবে ওপির ব্যবহারের ক্ষেত্রে এটি ব্যবহার করবেন তা দেখাতে পারেন?
jpaugh

1
এখানে একটি তাত্পর্য উদাহরণ রয়েছে: TEST_X টেবিল তৈরি করুন (একটি int, সিএসভি ভারচার (100)); টেস্ট_এক্স 1োকান 1, 'এ, বি' নির্বাচন করুন; টেস্ট_এক্স 2 এ সন্নিবেশ করুন, 'সি, ডি' নির্বাচন করুন; A নির্বাচন করুন, TEST_X এক্স ক্রস থেকে ডেটা dbo.splitString প্রয়োগ করুন (x.CSV, ',') Y; টেবিলটি ড্রপ করুন TEST_X
এস্কে

এটাই আমার দরকার ছিল! ধন্যবাদ.
নিতিন বদোলে

5

দয়া করে TSQL এর নীচে উল্লেখ করুন refer STRING_SPLIT ফাংশনটি কেবলমাত্র 130 এবং ততোধিকের সামঞ্জস্যতার স্তরের অধীনে উপলব্ধ।

TSQL:

DECLARE @stringValue NVARCHAR(400) = 'red,blue,green,yellow,black'  
DECLARE @separator CHAR = ','

SELECT [value]  As Colour
FROM STRING_SPLIT(@stringValue, @separator); 

ফলাফল:

রঙ

লাল নীল সবুজ হলুদ কালো


5

খুব দেরীতে তবে চেষ্টা করে দেখুন:

SELECT ColumnID, Column1, value  --Do not change 'value' name. Leave it as it is.
FROM tbl_Sample  
CROSS APPLY STRING_SPLIT(Tags, ','); --'Tags' is the name of column containing comma separated values

সুতরাং আমাদের এটি ছিল: টিবিএল_ নমুনা:

ColumnID|   Column1 |   Tags
--------|-----------|-------------
1       |   ABC     |   10,11,12    
2       |   PQR     |   20,21,22

এই কোয়েরিটি চালানোর পরে:

ColumnID|   Column1 |   value
--------|-----------|-----------
1       |   ABC     |   10
1       |   ABC     |   11
1       |   ABC     |   12
2       |   PQR     |   20
2       |   PQR     |   21
2       |   PQR     |   22

ধন্যবাদ!


STRING_SPLITছিমছাম কিন্তু এটা SQL সার্ভার 2016 প্রয়োজন docs.microsoft.com/en-us/sql/t-sql/functions/...
ক্রেগ সিলভার

মার্জিত সমাধান।
সংগ্রাম ননদখিল

3
DECLARE @id_list VARCHAR(MAX) = '1234,23,56,576,1231,567,122,87876,57553,1216'
DECLARE @table TABLE ( id VARCHAR(50) )
DECLARE @x INT = 0
DECLARE @firstcomma INT = 0
DECLARE @nextcomma INT = 0

SET @x = LEN(@id_list) - LEN(REPLACE(@id_list, ',', '')) + 1 -- number of ids in id_list

WHILE @x > 0
    BEGIN
        SET @nextcomma = CASE WHEN CHARINDEX(',', @id_list, @firstcomma + 1) = 0
                              THEN LEN(@id_list) + 1
                              ELSE CHARINDEX(',', @id_list, @firstcomma + 1)
                         END
        INSERT  INTO @table
        VALUES  ( SUBSTRING(@id_list, @firstcomma + 1, (@nextcomma - @firstcomma) - 1) )
        SET @firstcomma = CHARINDEX(',', @id_list, @firstcomma + 1)
        SET @x = @x - 1
    END

SELECT  *
FROM    @table

এটি আজুর এসকিউএল ডেটা গুদামে সীমাবদ্ধ এসকিউএল সমর্থন নিয়ে কাজ করে এমন কয়েকটি পদ্ধতির একটি।
অ্যারন

1
;WITH tmp(SomeID, OtherID, DataItem, Data) as (
    SELECT SomeID, OtherID, LEFT(Data, CHARINDEX(',',Data+',')-1),
        STUFF(Data, 1, CHARINDEX(',',Data+','), '')
FROM Testdata
WHERE Data > ''
)
SELECT SomeID, OtherID, Data
FROM tmp
ORDER BY SomeID

উপরের ক্যোয়ারিতে কেবলমাত্র সামান্য পরিবর্তন করা ...


6
আপনি কীভাবে সংক্ষেপে ব্যাখ্যা করতে পারবেন যে এটি গ্রহণযোগ্য উত্তরের সংস্করণে কীভাবে উন্নতি হয়?
লেইগ করুন

সমস্ত ইউনিয়ন নেই ... কম কোড। যেহেতু এটি ইউনিয়নের পরিবর্তে সমস্ত ইউনিয়ন ব্যবহার করছে, তাই পারফরম্যান্সের পার্থক্য হওয়া উচিত নয়?
তমুসজেরোয়েস

1
এটি তার থাকা সমস্ত সারি ফিরিয়ে দেয়নি। আমি নিশ্চিত নই যে ডেটা সম্পর্কে যা আছে তা ইউনিয়নের জন্য সমস্ত প্রয়োজন, তবে আপনার সমাধানটি মূল টেবিলের মতো একই সংখ্যক সারি ফিরিয়ে দিয়েছে।
ওডহেল সেটেন

1
(এখানে সমস্যাটি হ'ল পুনরাবৃত্ত অংশটি বাদ পড়ে ...)
এসকে রাহ্ন

আমাকে প্রত্যাশিত আউটপুট না দিয়ে কেবল পৃথক সারিতে প্রথম রেকর্ড প্রদান করছে
অঙ্কিত মিশরা

1

এই পদ্ধতির ব্যবহার করার সময় আপনাকে নিশ্চিত করতে হবে যে আপনার মানগুলির মধ্যে কোনওটিতেই এমন কিছু নেই যা অবৈধ এক্সএমএল - ব্যবহারকারী 1151923

আমি সবসময় এক্সএমএল পদ্ধতি ব্যবহার করি। নিশ্চিত করুন যে আপনি ভ্যালিড এক্সএমএল ব্যবহার করেছেন। বৈধ এক্সএমএল এবং পাঠ্যের মধ্যে রূপান্তর করতে আমার দুটি ফাংশন রয়েছে। (আমি সাধারণত গাড়ীর রিটার্নগুলি সরিয়ে নেওয়ার প্রবণতা করি কারণ আমার সাধারণত তাদের প্রয়োজন হয় না।

CREATE FUNCTION dbo.udf_ConvertTextToXML (@Text varchar(MAX)) 
    RETURNS varchar(MAX)
AS
    BEGIN
        SET @Text = REPLACE(@Text,CHAR(10),'')
        SET @Text = REPLACE(@Text,CHAR(13),'')
        SET @Text = REPLACE(@Text,'<','&lt;')
        SET @Text = REPLACE(@Text,'&','&amp;')
        SET @Text = REPLACE(@Text,'>','&gt;')
        SET @Text = REPLACE(@Text,'''','&apos;')
        SET @Text = REPLACE(@Text,'"','&quot;')
    RETURN @Text
END


CREATE FUNCTION dbo.udf_ConvertTextFromXML (@Text VARCHAR(MAX)) 
    RETURNS VARCHAR(max)
AS
    BEGIN
        SET @Text = REPLACE(@Text,'&lt;','<')
        SET @Text = REPLACE(@Text,'&amp;','&')
        SET @Text = REPLACE(@Text,'&gt;','>')
        SET @Text = REPLACE(@Text,'&apos;','''')
        SET @Text = REPLACE(@Text,'&quot;','"')
    RETURN @Text
END

1
আপনি যে কোডটি পেয়েছেন তাতে একটি ছোট সমস্যা আছে। এটি '<' কে '& amp; lt;' এ পরিবর্তন করবে; '& lt;' এর পরিবর্তে এটি করা উচিত। সুতরাং আপনাকে প্রথমে '&' এনকোড করা দরকার।
স্টুয়ার্ট

এই ধরনের ফাংশনের প্রয়োজন নেই ... কেবল অন্তর্নিহিত ক্ষমতাগুলি ব্যবহার করুন। এটি ব্যবহার করে দেখুন:SELECT (SELECT '<&> blah' + CHAR(13)+CHAR(10) + 'next line' FOR XML PATH(''))
শুনুগো

1

ক্রিয়া

CREATE FUNCTION dbo.SplitToRows (@column varchar(100), @separator varchar(10))
RETURNS @rtnTable TABLE
  (
  ID int identity(1,1),
  ColumnA varchar(max)
  )
 AS
BEGIN
    DECLARE @position int = 0
    DECLARE @endAt int = 0
    DECLARE @tempString varchar(100)

    set @column = ltrim(rtrim(@column))

    WHILE @position<=len(@column)
    BEGIN       
        set @endAt = CHARINDEX(@separator,@column,@position)
            if(@endAt=0)
            begin
            Insert into @rtnTable(ColumnA) Select substring(@column,@position,len(@column)-@position)
            break;
            end
        set @tempString = substring(ltrim(rtrim(@column)),@position,@endAt-@position)

        Insert into @rtnTable(ColumnA) select @tempString
        set @position=@endAt+1;
    END
    return
END

ব্যবহারের ক্ষেত্রে

select * from dbo.SplitToRows('T14; p226.0001; eee; 3554;', ';')

বা একাধিক ফলাফল সেট সহ কেবল একটি নির্বাচন করুন

DECLARE @column varchar(max)= '1234; 4748;abcde; 324432'
DECLARE @separator varchar(10) = ';'
DECLARE @position int = 0
DECLARE @endAt int = 0
DECLARE @tempString varchar(100)

set @column = ltrim(rtrim(@column))

WHILE @position<=len(@column)
BEGIN       
    set @endAt = CHARINDEX(@separator,@column,@position)
        if(@endAt=0)
        begin
        Select substring(@column,@position,len(@column)-@position)
        break;
        end
    set @tempString = substring(ltrim(rtrim(@column)),@position,@endAt-@position)

    select @tempString
    set @position=@endAt+1;
END

মাল্টিস্টেটমেন্ট টেবিলের মূল্যবান ফাংশনের ভিতরে কিছুক্ষণ লুপ ব্যবহার করে স্ট্রিংগুলি বিভক্ত করার সবচেয়ে খারাপ উপায়। ইতিমধ্যে এই প্রশ্নের উপর অনেক সেট ভিত্তিক বিকল্প আছে।
শান ল্যাঞ্জ

0

নীচে sql সার্ভারে কাজ করে 2008

select *, ROW_NUMBER() OVER(order by items) as row# 
from 
( select 134 myColumn1, 34 myColumn2, 'd,c,k,e,f,g,h,a' comaSeperatedColumn) myTable
    cross apply 
SPLIT (rtrim(comaSeperatedColumn), ',') splitedTable -- gives 'items'  column 

উত্স সারণী কলামগুলির সাথে বিভাজন সারণীর "আইটেম" সহ সমস্ত কার্তেসিয়ান পণ্য পাবেন।


0

আপনি ডেটা উত্তোলনের জন্য নিম্নলিখিত ফাংশনটি ব্যবহার করতে পারেন

CREATE FUNCTION [dbo].[SplitString]
(    
    @RowData NVARCHAR(MAX),
    @Delimeter NVARCHAR(MAX)
)
RETURNS @RtnValue TABLE 
(
    ID INT IDENTITY(1,1),
    Data NVARCHAR(MAX)
) 
AS
BEGIN 
    DECLARE @Iterator INT
    SET @Iterator = 1

    DECLARE @FoundIndex INT
    SET @FoundIndex = CHARINDEX(@Delimeter,@RowData)

    WHILE (@FoundIndex>0)
    BEGIN
        INSERT INTO @RtnValue (data)
        SELECT 
            Data = LTRIM(RTRIM(SUBSTRING(@RowData, 1, @FoundIndex - 1)))

        SET @RowData = SUBSTRING(@RowData,
                @FoundIndex + DATALENGTH(@Delimeter) / 2,
                LEN(@RowData))

        SET @Iterator = @Iterator + 1
        SET @FoundIndex = CHARINDEX(@Delimeter, @RowData)
    END

    INSERT INTO @RtnValue (Data)
    SELECT Data = LTRIM(RTRIM(@RowData))

    RETURN
END

মাল্টিস্টেটমেন্ট টেবিলের মূল্যবান ফাংশনের ভিতরে কিছুক্ষণ লুপ ব্যবহার করে স্ট্রিংগুলি বিভক্ত করার সবচেয়ে খারাপ উপায়। ইতিমধ্যে এই প্রশ্নের উপর অনেক সেট ভিত্তিক বিকল্প আছে।
শান ল্যাঞ্জ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.