টি-এসকিউএল বিভক্ত স্ট্রিং


139

আমার কাছে একটি এসকিউএল সার্ভার 2008 আর 2 কলাম রয়েছে যার একটি স্ট্রিং রয়েছে যা আমাকে কমা দ্বারা বিভক্ত করতে হবে। স্ট্যাক ওভারফ্লোতে আমি অনেক উত্তর দেখেছি কিন্তু সেগুলির কোনওটি আর 2 তে কাজ করে না। আমি নিশ্চিত করেছি যে কোনও বিভক্ত ফাংশন উদাহরণগুলিতে আমার কাছে নির্বাচনের অনুমতি রয়েছে। যে কোনও সহায়তা প্রশংসিত


7
এই মিলিয়ন উত্তর এক যে আমি মত stackoverflow.com/a/1846561/227755
nurettin

2
"তাদের কেউই কাজ করে না" মানে কি? আপনি আরো নির্দিষ্ট হতে পারে?
অ্যারন বারট্র্যান্ড

অ্যান্ডি আমাকে সঠিক দিকে নির্দেশ করেছিল কারণ আমি ফাংশনটি ভুলভাবে সম্পাদন করছিলাম। এই কারণেই অন্য স্ট্যাক উত্তরগুলির কোনওটিই কাজ করে না। আমার ভুল.
লি গ্রিন্ডন


mdq.RegexSplit"মাস্টার ডেটা পরিষেবাদি" অ্যাড-অনে একটি ফাংশন রয়েছে যা সাহায্য করতে পারে। অবশ্যই তদন্ত মূল্য
jpaugh

উত্তর:


233

আমি এই এসকিউএল আগে ব্যবহার করেছি যা আপনার পক্ষে কাজ করতে পারে: -

CREATE FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX) )
RETURNS
 @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

 DECLARE @name NVARCHAR(255)
 DECLARE @pos INT

 WHILE CHARINDEX(',', @stringToSplit) > 0
 BEGIN
  SELECT @pos  = CHARINDEX(',', @stringToSplit)  
  SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

  INSERT INTO @returnList 
  SELECT @name

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
 END

 INSERT INTO @returnList
 SELECT @stringToSplit

 RETURN
END

এবং এটি ব্যবহার করতে: -

SELECT * FROM dbo.splitstring('91,12,65,78,56,789')

1
ভাল এক, আমি ঠিক অনেক অনেক ধন্যবাদ খুঁজছিলাম
লি গ্রিন্ডন

2
অনেক ধন্যবাদ অ্যান্ডি বিভক্ত স্ট্রিংয়ের নির্দিষ্ট সূচীতে ফাংশনটিকে কোনও আইটেম ফেরত দেওয়ার জন্য আমি আপনার স্ক্রিপ্টে একটি ছোট বৃদ্ধি করেছি। এটি কেবল তখনই কার্যকর যখন আপনি যখন কলামের কাঠামোর কাঠামোটি পার্স করছেন। gist.github.com/klimaye/8147193
সিএফ_মিনিটেনার

1
আমি আমার গিথুব পৃষ্ঠায় এখানে কিছু উন্নতি (ব্যাকিং পরীক্ষার কেস সহ) পোস্ট করেছি । আমি এর উত্তর হিসাবে এটি পোস্ট করব স্ট্যাক ওভারফ্লো থ্রেডের যখন আমার" পোস্ট "সুরক্ষা" ছাড়িয়ে যাওয়ার জন্য যথেষ্ট পরিমাণ প্রতিনিধি থাকবে
এমপ্যাগ

8
যদিও এটি দুর্দান্ত উত্তর, এটি পুরানো ... প্রক্রিয়াগত পদ্ধতিগুলি (বিশেষত লুপগুলি) এড়াতে এমন কিছু ... নতুন উত্তরগুলি
খোঁজাই মূল্যবান

2
আমি @ শনুগোর সাথে পুরোপুরি একমত লুপিং বিভাজনগুলি কাজ করে তবে মারাত্মকভাবে ধীর হয়। এই স্কেলসার্ভারসেন্ট্রাল . com/articles/Tally+Table/72993 এর মতো কিছু আরও ভাল। আরও কিছু দুর্দান্ত সেট ভিত্তিক বিকল্পগুলি এখানে পাওয়া যাবে। sqlperformance.com/2012/07/t-sql-queries/split-strings
শান ল্যাঙ্গ

61

পুনরাবৃত্ত সিটিইগুলির পরিবর্তে এবং লুপগুলির পরিবর্তে, কেউ কি আরও সেট-ভিত্তিক পদ্ধতির বিবেচনা করেছে? নোট করুন যে এই ফাংশনটি প্রশ্নের জন্য লেখা হয়েছিল, যা এসকিউএল সার্ভার ২০০৮ এবং ডিলিমেটার হিসাবে কমাতে ভিত্তি করে ছিল । এসকিউএল সার্ভার ২০১ 2016 এবং এর উপরে (এবং সামঞ্জস্যতা স্তরের ১৩০ বা তারও বেশি), STRING_SPLIT()এটি একটি ভাল বিকল্প

CREATE FUNCTION dbo.SplitString
(
  @List     nvarchar(max),
  @Delim    nvarchar(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_columns) AS x WHERE Number <= LEN(@List)
      AND SUBSTRING(@Delim + @List, [Number], DATALENGTH(@Delim)/2) = @Delim
    ) AS y
  );
GO

আপনি যদি স্ট্রিংয়ের দৈর্ঘ্যের সীমাবদ্ধতা এড়াতে চান <= এ সারি সংখ্যা sys.all_columns( modelএসকিউএল সার্ভারে 9,980 ; আপনার নিজের ব্যবহারকারী ডাটাবেসে অনেক বেশি), তবে আপনি সংখ্যাগুলি অর্জনের জন্য অন্যান্য পদ্ধতির ব্যবহার করতে পারেন, যেমন আপনার নিজের সংখ্যা টেবিল তৈরি । আপনি সিস্টেম টেবিল ব্যবহার করতে বা নিজের তৈরি করতে পারবেন না এমন ক্ষেত্রে আপনি পুনরাবৃত্ত সিটিই ব্যবহার করতে পারেন:

CREATE FUNCTION dbo.SplitString
(
  @List     nvarchar(max),
  @Delim    nvarchar(255)
)
RETURNS TABLE WITH SCHEMABINDING
AS
   RETURN ( WITH n(n) AS (SELECT 1 UNION ALL SELECT n+1 
       FROM n WHERE n <= LEN(@List))
       SELECT [Value] = SUBSTRING(@List, n, 
       CHARINDEX(@Delim, @List + @Delim, n) - n)
       FROM n WHERE n <= LEN(@List)
      AND SUBSTRING(@Delim + @List, n, DATALENGTH(@Delim)/2) = @Delim
   );
GO

তবে স্ট্রিং> ১০০ টি অক্ষরের পুনরাবৃত্তি নিয়ে ত্রুটিগুলি এড়াতে আপনাকে বাইরের ক্যোয়ারিতে OPTION (MAXRECURSION 0)(বা MAXRECURSION <longest possible string length if < 32768>) সংযুক্ত করতে হবে। যদি এটিও ভাল বিকল্প না হয় তবে এই উত্তরটি দেখুন না হয় তবে মন্তব্যে নির্দেশিত হিসাবে ।

(এছাড়াও, ডিলিমিটারটি থাকতে হবে NCHAR(<=1228)Still এখনও কেন তা গবেষণা করছে))

স্প্লিট ফাংশনগুলিতে আরও কীভাবে (এবং প্রমাণ হিসাবে) লুপগুলি এবং পুনরাবৃত্ত সিটিই স্কেল করে না, এবং আরও ভাল বিকল্প, যদি অ্যাপ্লিকেশন স্তর থেকে বিভাজন স্ট্রিংগুলি আসে:


1
এই পদ্ধতির ক্ষেত্রে একটি ছোট্ট বাগ রয়েছে যেখানে স্ট্রিংয়ের শেষে একটি নাল মান থাকবে - যেমন '1,2,, 4,' - - হিসাবে চূড়ান্ত মানটি বিশ্লেষণ করা হয়নি। এই ত্রুটিটি সংশোধন করতে "WHERE সংখ্যা <= LEN (@ তালিকা)" অভিব্যক্তিটি "WHERE সংখ্যা <= LEN (@ তালিকা) + 1" দিয়ে প্রতিস্থাপন করা উচিত।
সিলভাইনল

@ সিলভাইনল আমি অনুমান করি যে আপনি কী আচরণ চান তার উপর নির্ভর করে। আমার অভিজ্ঞতায়, বেশিরভাগ লোকেরা কোনও ট্রেলিং কমা উপেক্ষা করতে চায় কারণ তারা সত্যিকার অর্থে কোনও উপাদানকে উপস্থাপন করে না (ফাঁকা স্ট্রিংয়ের কত কপি আপনার প্রয়োজন)? যাইহোক, এটি করার আসল উপায় - আপনি যদি দ্বিতীয় লিঙ্কটি অনুসরণ করেন - তা হ'ল ধীরে ধীরে টি-এসকিউএল-তে বড় কুৎসিত স্ট্রিংগুলিকে বিভক্ত করে চারদিকে গোলমাল করা।
অ্যারন বারট্রান্ড

1
যেমনটি আপনি বলেছেন, বেশিরভাগ লোকেরা কোনও অনুচর কমা উপেক্ষা করতে চায় তবে হায় হায়, সব কিছু নয়। আমি মনে করি যে আরও একটি সম্পূর্ণ সমাধান এই ক্ষেত্রে কী করা উচিত তা নির্দিষ্ট করার জন্য একটি প্যারামিটার যুক্ত করা হবে তবে আমার মন্তব্যটি এই সম্ভাবনাটি সম্পর্কে যে কেউ ভুলে না যায় তা নিশ্চিত করার জন্য এটি কেবলমাত্র একটি সামান্য নোট, কারণ এটি অনেক ক্ষেত্রেই সত্যিকারের হতে পারে।
সিলেভেনএল

এই ফাংশনটির সাথে আমার একটি অদ্ভুত আচরণ রয়েছে। আমি যদি প্যারামিটার হিসাবে সরাসরি একটি স্ট্রিং ব্যবহার করি - এটি কাজ করে। আমার যদি একটি ভারচার থাকে তবে তা হয় না। আপনি সহজেই পুনরুত্পাদন করতে পারেন: আচারচারকে বর্ণচর সেট আক্রমণকারী হিসাবে ঘোষণা করুন = 'টা; এএ; কিউকিউ' নির্বাচন মূল্য [ডিবিও] থেকে। আ; কিউকি ','; ')
প্যাট্রিক দেশজার্ডিনস

আমি এই পদ্ধতিকে পছন্দ করি তবে এর দ্বারা প্রত্যাবর্তিত বস্তুর সংখ্যা যদি sys.all_objectsইনপুট স্ট্রিংয়ের অক্ষরের সংখ্যার চেয়ে কম হয় তবে এটি স্ট্রিংটি কেটে যাবে এবং মানগুলি নিখোঁজ হয়ে যাবে। যেহেতু sys.all_objectsসারি তৈরি করতে হ্যাকের সামান্য হিসাবে ব্যবহৃত হচ্ছে, তাই এটি করার আরও ভাল উপায় আছে, যেমন এই উত্তর
নাকলস

56

পরিশেষে এসকিউএল সার্ভার ২০১ the এ অপেক্ষা শেষ হয়েছে তারা স্প্লিট স্ট্রিংয়ের কাজটি চালু করেছে:STRING_SPLIT

select * From STRING_SPLIT ('a,b', ',') cs 

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

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


5
স্পষ্টতই আপডেট হওয়া সার্ভারগুলির সাথে স্ট্রিংগুলিকে কীভাবে বিভক্ত করা যায় তার প্রশ্নের উত্তর দেয়, তবে আমাদের মধ্যে যারা এখনও 2008 / 2008R2 এ আটকে আছে তাদের অন্য উত্তরগুলির সাথে এখানে যেতে হবে।
এমপ্যাগ

2
আপনার আপনার ডাটাবেসে সামঞ্জস্যের স্তরটি একবার দেখে নেওয়া দরকার। এটি যদি 130 এর চেয়ে কম হয় তবে আপনি STRING_SPLIT ফাংশনটি ব্যবহার করতে পারবেন না।
লুইস তেজোন

প্রকৃতপক্ষে, যদি সামঞ্জস্যতা 130 না হয় এবং আপনি 2016 (বা অ্যাজুরি এসকিউএল) চালাচ্ছেন তবে আপনি 130 ব্যবহার করে সামঞ্জস্যতা সেট করতে পারেন: ALTER DATABASE
ডাটাবেসনাম

23

এটি করার সহজতম উপায় হ'ল XMLফর্ম্যাট ব্যবহার করে।

1. টেবিল ছাড়াই সারিগুলিতে স্ট্রিং রূপান্তর করা

প্রশ্ন

DECLARE @String varchar(100) = 'String1,String2,String3'
-- To change ',' to any other delimeter, just change ',' to your desired one
DECLARE @Delimiter CHAR = ','    

SELECT LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'Value' 
FROM  
(     
     SELECT CAST ('<M>' + REPLACE(@String, @Delimiter, '</M><M>') + '</M>' AS XML) AS Data            
) AS A 
CROSS APPLY Data.nodes ('/M') AS Split(a)

ফলাফল

 x---------x
 | Value   |
 x---------x
 | String1 |
 | String2 |
 | String3 |
 x---------x

২. প্রতিটি সিএসভি সারির জন্য একটি আইডি রয়েছে এমন একটি টেবিল থেকে সারিগুলিতে রূপান্তর

উত্স টেবিল

 x-----x--------------------------x
 | Id  |           Value          |
 x-----x--------------------------x
 |  1  |  String1,String2,String3 |
 |  2  |  String4,String5,String6 |     
 x-----x--------------------------x

প্রশ্ন

-- To change ',' to any other delimeter, just change ',' before '</M><M>' to your desired one
DECLARE @Delimiter CHAR = ','

SELECT ID,LTRIM(RTRIM(Split.a.value('.', 'VARCHAR(100)'))) 'Value' 
FROM  
(     
     SELECT ID,CAST ('<M>' + REPLACE(VALUE, @Delimiter, '</M><M>') + '</M>' AS XML) AS Data            
     FROM TABLENAME
) AS A 
CROSS APPLY Data.nodes ('/M') AS Split(a)

ফলাফল

 x-----x----------x
 | Id  |  Value   |
 x-----x----------x
 |  1  |  String1 |
 |  1  |  String2 |  
 |  1  |  String3 |
 |  2  |  String4 |  
 |  2  |  String5 |
 |  2  |  String6 |     
 x-----x----------x

@Stringনিষিদ্ধ অক্ষর থাকলে এই পদ্ধতিটি ভেঙে যাবে ... আমি এই সমস্যাটি কাটিয়ে উঠতে কেবল একটি উত্তর পোস্ট করেছি ।
শুনুগো

9

+4একটি জিপ কোড থেকে এড়ানোর জন্য আমার দ্রুত উপায় প্রয়োজন ।

UPDATE #Emails 
  SET ZIPCode = SUBSTRING(ZIPCode, 1, (CHARINDEX('-', ZIPCODE)-1)) 
  WHERE ZIPCode LIKE '%-%'

কোন প্রকার ... কোনও ইউডিএফ নেই ... কেবলমাত্র একটি টাইট সামান্য ইনলাইন কমান্ড যা এটি করা উচিত তা করে। অভিনব নয়, মার্জিত নয়।

প্রয়োজন অনুসারে ডিলিমিটার পরিবর্তন করুন এবং এটি যে কোনও কিছুর জন্য কাজ করবে।


4
প্রশ্নটি এটাই নয়। ওপির মান '234,542,23' এর মতো রয়েছে এবং তারা এটিকে তিনটি সারিতে বিভক্ত করতে চায় ... প্রথম সারিতে: ২৩৪, ২ য় সারিতে: ৫৪২, তৃতীয় সারিতে: ২৩. এসকিউএল করা এটি একটি জটিল বিষয়।
কোডুলিকে

7

যদি আপনি প্রতিস্থাপন

WHILE CHARINDEX(',', @stringToSplit) > 0

সঙ্গে

WHILE LEN(@stringToSplit) > 0

আপনি লুপ পরে শেষ সন্নিবেশ শেষ করতে পারেন!

CREATE FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX) )
RETURNS
 @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

 DECLARE @name NVARCHAR(255)
 DECLARE @pos INT

 WHILE LEN(@stringToSplit) > 0
 BEGIN
  SELECT @pos  = CHARINDEX(',', @stringToSplit)


if @pos = 0
        SELECT @pos = LEN(@stringToSplit)


  SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

  INSERT INTO @returnList 
  SELECT @name

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
 END

 RETURN
END

এর ফলে শেষ উপাদানটির শেষ চরিত্রটি কেটে যাবে। যেমন "AL, AL" হয়ে যাবে "AL" | "এ" অর্থাৎ "এবিসি, এবিসি, এবিসি" হয়ে উঠবে "এবিসি" | | "এবিসি" | "এবি"
মাইক্রোসফ্ট বিকাশকারী

সংযোজন +1করতে SELECT @pos = LEN(@stringToSplit)প্রদর্শিত হয় যে সমস্যা মোকাবেলার। তবে আপনি সাবস্ক্রিংয়ের তৃতীয় প্যারামিটারে যোগ না করা পর্যন্ত রিটার্নটি SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)ফিরে আসবে । অথবা আপনি সেই নিয়োগটি প্রতিস্থাপন করতে পারেনInvalid length parameter passed to the LEFT or SUBSTRING function+1SET @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, 4000) --MAX len of nvarchar is 4000
এমপ্যাগ

1
আমি আমার গিথুব পৃষ্ঠায় এখানে কিছু উন্নতি (ব্যাকিং পরীক্ষার কেস সহ) পোস্ট করেছি । আমি " স্ট্যাক ওভারফ্লো থ্রেডের উত্তর হিসাবে পোস্ট করব যখন আমার" পোস্ট "সুরক্ষা" ছাড়িয়ে যাওয়ার জন্য যথেষ্ট পরিমাণ প্রতিনিধি থাকবে
এমপ্যাগ

আমিও উপরের টেরি দ্বারা চিহ্নিত ইস্যুটি উল্লেখ করেছি। তবে @ অ্যাভিজি দ্বারা প্রদত্ত যুক্তিটি এতটাই দুর্দান্ত যে এটি টোকেনের দীর্ঘ তালিকার জন্য মাঝখানে ব্যর্থ হয় না। যাচাই করার জন্য এই পরীক্ষার কলটি ব্যবহার করে দেখুন (এই কলটি 969 টোকেন ফিরবে) dbo.splitstring (* 'টোকেন 1, টোকেন 2 ,,,,,,,, টোকেন 969') থেকে * নির্বাচন করুন এবং তারপরে ফলাফল পরীক্ষা করার জন্য আমি এমপ্যাগের দেওয়া কোডটি চেষ্টা করেছিলাম উপরে কল করুন এবং এটি পাওয়া গেছে মাত্র 365 টোকেন। অবশেষে আমি উপরে অ্যাভিজি দ্বারা কোড স্থির করেছি এবং নীচে একটি নতুন উত্তর হিসাবে বাগ ফ্রি ফাংশন পোস্ট করেছি কারণ এখানে মন্তব্য কেবল সীমাবদ্ধ পাঠ্যকেই অনুমতি দেয়। উত্তরটি চেষ্টা করে দেখতে আমার নামের নিচে চেক করুন।
জেমুনু আর উইক্রেমাসিংহে

3

স্ট্রিং বিভাজনের জন্য সমস্ত ফাংশন যা কোনও ধরণের লুপ-ইন (পুনরাবৃত্তি) ব্যবহার করে তাদের কার্যকারিতা খারাপ থাকে। সেগুলি সেট-ভিত্তিক সমাধান সহ প্রতিস্থাপন করা উচিত।

এই কোডটি দুর্দান্ত কার্যকর করে।

CREATE FUNCTION dbo.SplitStrings
(
   @List       NVARCHAR(MAX),
   @Delimiter  NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
   RETURN 
   (  
      SELECT Item = y.i.value('(./text())[1]', 'nvarchar(4000)')
      FROM 
      ( 
        SELECT x = CONVERT(XML, '<i>' 
          + REPLACE(@List, @Delimiter, '</i><i>') 
          + '</i>').query('.')
      ) AS a CROSS APPLY x.nodes('i') AS y(i)
   );
GO

@Listনিষিদ্ধ অক্ষর থাকলে এই পদ্ধতিটি ভেঙে যাবে ... আমি এই সমস্যাটি কাটিয়ে উঠতে কেবল একটি উত্তর পোস্ট করেছি ।
শুনুগো

আমি আপনার প্রতিক্রিয়াটিকে সমর্থন করছি কারণ আপনার স্থানের সাথে সীমানা হিসাবে কাজ এবং সর্বোচ্চ ভোট প্রাপ্ত কেউ করেনি
কেএমসি

3

এক্সএমএল উপাদানগুলির সাথে প্রায়শই ব্যবহৃত ব্যবহারটি নিষিদ্ধ চরিত্রগুলির ক্ষেত্রে বিরতি। এই পদ্ধতিটি যে কোনও ধরণের চরিত্রের সাথে, এমনকি সেমিকোলনটি ডিলিমেটার হিসাবে ব্যবহার করার জন্য approach

কৌশলটি হ'ল, প্রথমে SELECT SomeString AS [*] FOR XML PATH('')সমস্ত নিষিদ্ধ চরিত্রগুলি সঠিকভাবে পালানোর জন্য ব্যবহার করুন । এই কারণ, কেন আমি সীমানার হিসাবে ঝামেলা এড়াতে আমি কেন একটি যাদু মানকে ডিলিমিটারটি প্রতিস্থাপন করি ;

DECLARE @Dummy TABLE (ID INT, SomeTextToSplit NVARCHAR(MAX))
INSERT INTO @Dummy VALUES
 (1,N'A&B;C;D;E, F')
,(2,N'"C" & ''D'';<C>;D;E, F');

DECLARE @Delimiter NVARCHAR(10)=';'; --special effort needed (due to entities coding with "&code;")!

WITH Casted AS
(
    SELECT *
          ,CAST(N'<x>' + REPLACE((SELECT REPLACE(SomeTextToSplit,@Delimiter,N'§§Split$me$here§§') AS [*] FOR XML PATH('')),N'§§Split$me$here§§',N'</x><x>') + N'</x>' AS XML) AS SplitMe
    FROM @Dummy
)
SELECT Casted.ID
      ,x.value(N'.',N'nvarchar(max)') AS Part 
FROM Casted
CROSS APPLY SplitMe.nodes(N'/x') AS A(x)

ফলাফল

ID  Part
1   A&B
1   C
1   D
1   E, F
2   "C" & 'D'
2   <C>
2   D
2   E, F

2

আমাকে সম্প্রতি এমন কিছু লিখতে হয়েছিল। সমাধানটি আমি এখানে নিয়ে এসেছি। এটি যে কোনও ডিলিমিটার স্ট্রিংয়ের জন্য সাধারণীকরণ করা হয় এবং আমি মনে করি এটি কিছুটা ভাল সম্পাদন করবে:

CREATE FUNCTION [dbo].[SplitString] 
    ( @string nvarchar(4000)
    , @delim nvarchar(100) )
RETURNS
    @result TABLE 
        ( [Value] nvarchar(4000) NOT NULL
        , [Index] int NOT NULL )
AS
BEGIN
    DECLARE @str nvarchar(4000)
          , @pos int 
          , @prv int = 1

    SELECT @pos = CHARINDEX(@delim, @string)
    WHILE @pos > 0
    BEGIN
        SELECT @str = SUBSTRING(@string, @prv, @pos - @prv)
        INSERT INTO @result SELECT @str, @prv

        SELECT @prv = @pos + LEN(@delim)
             , @pos = CHARINDEX(@delim, @string, @pos + 1)
    END

    INSERT INTO @result SELECT SUBSTRING(@string, @prv, 4000), @prv
    RETURN
END

1

সিটিই ব্যবহার করে একটি সমাধান, যদি কারও এটির প্রয়োজন হয় (আমাকে বাদ দিয়ে, যারা স্পষ্টতই করেছিলেন, সে কারণেই আমি এটি লিখেছিলাম)।

declare @StringToSplit varchar(100) = 'Test1,Test2,Test3';
declare @SplitChar varchar(10) = ',';

with StringToSplit as (
  select 
      ltrim( rtrim( substring( @StringToSplit, 1, charindex( @SplitChar, @StringToSplit ) - 1 ) ) ) Head
    , substring( @StringToSplit, charindex( @SplitChar, @StringToSplit ) + 1, len( @StringToSplit ) ) Tail

  union all

  select
      ltrim( rtrim( substring( Tail, 1, charindex( @SplitChar, Tail ) - 1 ) ) ) Head
    , substring( Tail, charindex( @SplitChar, Tail ) + 1, len( Tail ) ) Tail
  from StringToSplit
  where charindex( @SplitChar, Tail ) > 0

  union all

  select
      ltrim( rtrim( Tail ) ) Head
    , '' Tail
  from StringToSplit
  where charindex( @SplitChar, Tail ) = 0
    and len( Tail ) > 0
)
select Head from StringToSplit

1

এটি আরও সংকীর্ণ অনুসারে তৈরি। আমি যখন এটি করি তখন আমার কাছে অনন্য আইডির একটি কমা-বিস্মৃত তালিকা থাকে (আইএনটি বা বিজিআইএনটি), যা আমি অন্য টেবিলের অভ্যন্তরীণ জোড় হিসাবে ব্যবহার করতে একটি টেবিল হিসাবে কাস্ট করতে চাই যার INT বা BIGINT এর প্রাথমিক কী থাকে। আমি চাই যে একটি ইন-লাইন টেবিল-মূল্যবান ফাংশনটি ফিরে আসুক যাতে আমার সবচেয়ে কার্যকর যোগদান সম্ভব হয়।

নমুনা ব্যবহার হবে:

 DECLARE @IDs VARCHAR(1000);
 SET @IDs = ',99,206,124,8967,1,7,3,45234,2,889,987979,';
 SELECT me.Value
 FROM dbo.MyEnum me
 INNER JOIN dbo.GetIntIdsTableFromDelimitedString(@IDs) ids ON me.PrimaryKey = ids.ID

আমি http://sqlrecords.blogspot.com/2012/11/converting-delimited-list-to-table.html থেকে ধারণাটি চুরি করে এটিকে ইন-লাইন টেবিলের কদর হিসাবে পরিবর্তন করে INT হিসাবে কাস্ট করেছি।

create function dbo.GetIntIDTableFromDelimitedString
    (
    @IDs VARCHAR(1000)  --this parameter must start and end with a comma, eg ',123,456,'
                        --all items in list must be perfectly formatted or function will error
)
RETURNS TABLE AS
 RETURN

SELECT
    CAST(SUBSTRING(@IDs,Nums.number + 1,CHARINDEX(',',@IDs,(Nums.number+2)) - Nums.number - 1) AS INT) AS ID 
FROM   
     [master].[dbo].[spt_values] Nums
WHERE Nums.Type = 'P' 
AND    Nums.number BETWEEN 1 AND DATALENGTH(@IDs)
AND    SUBSTRING(@IDs,Nums.number,1) = ','
AND    CHARINDEX(',',@IDs,(Nums.number+1)) > Nums.number;

GO

1

এখানে একটি সঠিক সংস্করণ রয়েছে তবে আমি ভেবেছিলাম যে তাদের পিছনে কমা থাকলে সামান্য ত্রুটি সহিষ্ণুতা যুক্ত করা ভাল হবে তবে আপনি এটি কোনও ফাংশন হিসাবে নয় বরং কোডের বড় অংশের অংশ হিসাবে ব্যবহার করতে পারেন । কেবলমাত্র আপনি যদি একবার এটি ব্যবহার করেন তবে কোনও ফাংশনের প্রয়োজন নেই। এটি পূর্ণসংখ্যার জন্যও (যা এর জন্য আমার এটির প্রয়োজন ছিল) তাই আপনাকে আপনার ডেটা ধরণের পরিবর্তন করতে হতে পারে।

DECLARE @StringToSeperate VARCHAR(10)
SET @StringToSeperate = '1,2,5'

--SELECT @StringToSeperate IDs INTO #Test

DROP TABLE #IDs
CREATE TABLE #IDs (ID int) 

DECLARE @CommaSeperatedValue NVARCHAR(255) = ''
DECLARE @Position INT = LEN(@StringToSeperate)

--Add Each Value
WHILE CHARINDEX(',', @StringToSeperate) > 0
BEGIN
    SELECT @Position  = CHARINDEX(',', @StringToSeperate)  
    SELECT @CommaSeperatedValue = SUBSTRING(@StringToSeperate, 1, @Position-1)

    INSERT INTO #IDs 
    SELECT @CommaSeperatedValue

    SELECT @StringToSeperate = SUBSTRING(@StringToSeperate, @Position+1, LEN(@StringToSeperate)-@Position)

END

--Add Last Value
IF (LEN(LTRIM(RTRIM(@StringToSeperate)))>0)
BEGIN
    INSERT INTO #IDs
    SELECT SUBSTRING(@StringToSeperate, 1, @Position)
END

SELECT * FROM #IDs

আপনি যদি লুপটির SET @StringToSeperate = @StringToSeperate+','অবিলম্বে উপস্থিত হন তবে WHILEআমি মনে করি আপনি "শেষ মান যোগ করুন" ব্লকটি মুছে ফেলতে সক্ষম হতে পারেন। গিথুব-
এমপ্যাগ

এটি কোন উত্তর ভিত্তিক? এখানে প্রচুর উত্তর রয়েছে এবং এটি কিছুটা বিভ্রান্তিকর। ধন্যবাদ।
jpaugh

1

আমি অ্যান্ডি রবিনসনের ফাংশনটি কিছুটা পরিবর্তন করেছি। এখন আপনি রিটার্ন টেবিল থেকে কেবল প্রয়োজনীয় অংশটি চয়ন করতে পারেন:

CREATE FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(MAX) )

RETURNS

 @returnList TABLE ([numOrder] [tinyint] , [Name] [nvarchar] (500)) AS
BEGIN

 DECLARE @name NVARCHAR(255)

 DECLARE @pos INT

 DECLARE @orderNum INT

 SET @orderNum=0

 WHILE CHARINDEX('.', @stringToSplit) > 0

 BEGIN
    SELECT @orderNum=@orderNum+1;
  SELECT @pos  = CHARINDEX('.', @stringToSplit)  
  SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

  INSERT INTO @returnList 
  SELECT @orderNum,@name

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
 END
    SELECT @orderNum=@orderNum+1;
 INSERT INTO @returnList
 SELECT @orderNum, @stringToSplit

 RETURN
END


Usage:

SELECT Name FROM dbo.splitstring('ELIS.YD.CRP1.1.CBA.MDSP.T389.BT') WHERE numOrder=5


1

যদি আপনার ন্যূনতম কোড সহ সাধারণ ক্ষেত্রে দ্রুত অ্যাডহক সমাধানের প্রয়োজন হয়, তবে এই পুনরাবৃত্ত সিটিই দ্বি-লাইনার এটি করবে:

DECLARE @s VARCHAR(200) = ',1,2,,3,,,4,,,,5,'

;WITH
a AS (SELECT i=-1, j=0 UNION ALL SELECT j, CHARINDEX(',', @s, j + 1) FROM a WHERE j > i),
b AS (SELECT SUBSTRING(@s, i+1, IIF(j>0, j, LEN(@s)+1)-i-1) s FROM a WHERE i >= 0)
SELECT * FROM b

হয় এটিকে এককভাবে বিবৃতি হিসাবে ব্যবহার করুন বা উপরের সিটিইগুলি আপনার যে কোনও প্রশ্নের সাথে যুক্ত করুন এবং ফলস্বরূপ সারণিতে আপনি যোগ দিতে সক্ষম হবেন b পরবর্তী কোনও অভিব্যক্তিতে ব্যবহারের জন্য অন্যদের সাথে ।

সম্পাদনা করুন (শ্নুগো দ্বারা)

আপনি যদি কোনও কাউন্টার যুক্ত করেন তবে তালিকার সাথে আপনি একটি অবস্থান সূচক পাবেন:

DECLARE @s VARCHAR(200) = '1,2333,344,4'

;WITH
a AS (SELECT n=0, i=-1, j=0 UNION ALL SELECT n+1, j, CHARINDEX(',', @s, j+1) FROM a WHERE j > i),
b AS (SELECT n, SUBSTRING(@s, i+1, IIF(j>0, j, LEN(@s)+1)-i-1) s FROM a WHERE i >= 0)
SELECT * FROM b;

ফলাফল:

n   s
1   1
2   2333
3   344
4   4

আমি এই পদ্ধতির পছন্দ। আমি আশা করি আপনি আপত্তি করবেন না, যে আমি সরাসরি আপনার উত্তরে কিছু বর্ধন যোগ করেছি। যেকোন সুবিধাজনক উপায়ে এটি সম্পাদন করতে দ্বিধা বোধ করুন ...
শনুগো

1

আমি মানগুলিকে উপাদানগুলিতে মুড়িয়ে xML রুটটি নিয়ে যাই (এম তবে কিছুই কার্যকর হয় না):

declare @v nvarchar(max) = '100,201,abcde'

select 
    a.value('.', 'varchar(max)')
from
    (select cast('<M>' + REPLACE(@v, ',', '</M><M>') + '</M>' AS XML) as col) as A
    CROSS APPLY A.col.nodes ('/M') AS Split(a)

0

এখানে একটি সংস্করণ যা প্যাটিনডেক্স ব্যবহার করে কোনও প্যাটার্নে বিভক্ত হতে পারে, উপরের পোস্টটির একটি সাধারণ অভিযোজন। আমার একটি কেস হয়েছে যেখানে আমার কাছে স্ট্রিং বিভক্ত করার দরকার ছিল যাতে একাধিক বিভাজক অক্ষর রয়েছে।


alter FUNCTION dbo.splitstring ( @stringToSplit VARCHAR(1000), @splitPattern varchar(10) )
RETURNS
 @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

 DECLARE @name NVARCHAR(255)
 DECLARE @pos INT

 WHILE PATINDEX(@splitPattern, @stringToSplit) > 0
 BEGIN
  SELECT @pos  = PATINDEX(@splitPattern, @stringToSplit)  
  SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

  INSERT INTO @returnList 
  SELECT @name

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
 END

 INSERT INTO @returnList
 SELECT @stringToSplit

 RETURN
END
select * from dbo.splitstring('stringa/stringb/x,y,z','%[/,]%');

ফলাফল এর মত দেখাচ্ছে

স্ট্রিংআ স্ট্রিংব x y z


0

ব্যক্তিগতভাবে আমি এই ফাংশনটি ব্যবহার করি:

ALTER FUNCTION [dbo].[CUST_SplitString]
(
    @String NVARCHAR(4000),
    @Delimiter NCHAR(1)
)
RETURNS TABLE 
AS
RETURN 
(
    WITH Split(stpos,endpos) 
    AS(
        SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
        UNION ALL
        SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1) 
        FROM Split
        WHERE endpos > 0
    )
    SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
        'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
    FROM Split
)

0

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

CREATE FUNCTION uft_DoubleSplitter 
(   
    -- Add the parameters for the function here
    @String VARCHAR(4000), 
    @Splitter1 CHAR,
    @Splitter2 CHAR
)
RETURNS @Result TABLE (Id INT,MId INT,SValue VARCHAR(4000))
AS
BEGIN
DECLARE @FResult TABLE(Id INT IDENTITY(1, 1),
                   SValue VARCHAR(4000))
DECLARE @SResult TABLE(Id INT IDENTITY(1, 1),
                   MId INT,
                   SValue VARCHAR(4000))
SET @String = @String+@Splitter1

WHILE CHARINDEX(@Splitter1, @String) > 0
    BEGIN
       DECLARE @WorkingString VARCHAR(4000) = NULL

       SET @WorkingString = SUBSTRING(@String, 1, CHARINDEX(@Splitter1, @String) - 1)
       --Print @workingString

       INSERT INTO @FResult
       SELECT CASE
            WHEN @WorkingString = '' THEN NULL
            ELSE @WorkingString
            END

       SET @String = SUBSTRING(@String, LEN(@WorkingString) + 2, LEN(@String))

    END
IF ISNULL(@Splitter2, '') != ''
    BEGIN
       DECLARE @OStartLoop INT
       DECLARE @OEndLoop INT

       SELECT @OStartLoop = MIN(Id),
            @OEndLoop = MAX(Id)
       FROM @FResult

       WHILE @OStartLoop <= @OEndLoop
          BEGIN
             DECLARE @iString VARCHAR(4000)
             DECLARE @iMId INT

             SELECT @iString = SValue+@Splitter2,
                   @iMId = Id
             FROM @FResult
             WHERE Id = @OStartLoop

             WHILE CHARINDEX(@Splitter2, @iString) > 0
                BEGIN
                    DECLARE @iWorkingString VARCHAR(4000) = NULL

                    SET @IWorkingString = SUBSTRING(@iString, 1, CHARINDEX(@Splitter2, @iString) - 1)

                    INSERT INTO @SResult
                    SELECT @iMId,
                         CASE
                         WHEN @iWorkingString = '' THEN NULL
                         ELSE @iWorkingString
                         END

                    SET @iString = SUBSTRING(@iString, LEN(@iWorkingString) + 2, LEN(@iString))

                END

             SET @OStartLoop = @OStartLoop + 1
          END
       INSERT INTO @Result
       SELECT MId AS PrimarySplitID,
            ROW_NUMBER() OVER (PARTITION BY MId ORDER BY Mid, Id) AS SecondarySplitID ,
            SValue
       FROM @SResult
    END
ELSE
    BEGIN
       INSERT INTO @Result
       SELECT Id AS PrimarySplitID,
            NULL AS SecondarySplitID,
            SValue
       FROM @FResult
    END
RETURN

ব্যবহার:

--FirstSplit
SELECT * FROM uft_DoubleSplitter('ValueA=ValueB=ValueC=ValueD==ValueE&ValueA=ValueB=ValueC===ValueE&ValueA=ValueB==ValueD===','&',NULL)

--Second Split
SELECT * FROM uft_DoubleSplitter('ValueA=ValueB=ValueC=ValueD==ValueE&ValueA=ValueB=ValueC===ValueE&ValueA=ValueB==ValueD===','&','=')

সম্ভাব্য ব্যবহার (প্রতিটি বিভাজনের দ্বিতীয় মান পান):

SELECT fn.SValue
FROM uft_DoubleSplitter('ValueA=ValueB=ValueC=ValueD==ValueE&ValueA=ValueB=ValueC===ValueE&ValueA=ValueB==ValueD===', '&', '=')AS fn
WHERE fn.mid = 2

0

এখানে একটি উদাহরণ যা আপনি ফাংশন হিসাবে ব্যবহার করতে পারেন বা পদ্ধতিতে একই যুক্তি রাখতে পারেন। - টিপুন * [ডিবিও] থেকে .fn_SplitString;

CREATE FUNCTION [dbo].[fn_SplitString]
(@CSV VARCHAR(MAX), @Delimeter VARCHAR(100) = ',')
       RETURNS @retTable TABLE 
(

    [value] VARCHAR(MAX) NULL
)AS

BEGIN

DECLARE
       @vCSV VARCHAR (MAX) = @CSV,
       @vDelimeter VARCHAR (100) = @Delimeter;

IF @vDelimeter = ';'
BEGIN
    SET @vCSV = REPLACE(@vCSV, ';', '~!~#~');
    SET @vDelimeter = REPLACE(@vDelimeter, ';', '~!~#~');
END;

SET @vCSV = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@vCSV, '&', '&amp;'), '<', '&lt;'), '>', '&gt;'), '''', '&apos;'), '"', '&quot;');

DECLARE @xml XML;

SET @xml = '<i>' + REPLACE(@vCSV, @vDelimeter, '</i><i>') + '</i>';

INSERT INTO @retTable
SELECT
       x.i.value('.', 'varchar(max)') AS COLUMNNAME
  FROM @xml.nodes('//i')AS x(i);

 RETURN;
END;

@vCSVনিষিদ্ধ অক্ষর থাকলে এই পদ্ধতিটি ভেঙে যাবে ... আমি এই সমস্যাটি কাটিয়ে উঠতে কেবল একটি উত্তর পোস্ট করেছি ।
শুনুগো

0

একটি recursive cte ভিত্তিক সমাধান

declare @T table (iden int identity, col1 varchar(100));
insert into @T(col1) values
       ('ROOT/South America/Lima/Test/Test2')
     , ('ROOT/South America/Peru/Test/Test2')
     , ('ROOT//South America/Venuzuala ')
     , ('RtT/South America / ') 
     , ('ROOT/South Americas// '); 
declare @split char(1) = '/';
select @split as split;
with cte as 
(  select t.iden, case when SUBSTRING(REVERSE(rtrim(t.col1)), 1, 1) = @split then LTRIM(RTRIM(t.col1)) else LTRIM(RTRIM(t.col1)) + @split end  as col1, 0 as pos                             , 1 as cnt
   from @T t
   union all 
   select t.iden, t.col1                                                                                                                              , charindex(@split, t.col1, t.pos + 1), cnt + 1 
   from cte t 
   where charindex(@split, t.col1, t.pos + 1) > 0 
)
select t1.*, t2.pos, t2.cnt
     , ltrim(rtrim(SUBSTRING(t1.col1, t1.pos+1, t2.pos-t1.pos-1))) as bingo
from cte t1 
join cte t2 
  on t2.iden = t1.iden 
 and t2.cnt  = t1.cnt+1
 and t2.pos > t1.pos 
order by t1.iden, t1.cnt;

0

এটি অ্যান্ডি রবার্টসনের উত্তরের ভিত্তিতে তৈরি, আমার কমা ব্যতীত অন্য একটি ডিলিমিটারের দরকার ছিল needed

CREATE FUNCTION dbo.splitstring ( @stringToSplit nvarchar(MAX), @delim nvarchar(max))
RETURNS
 @returnList TABLE ([value] [nvarchar] (MAX))
AS
BEGIN

 DECLARE @value NVARCHAR(max)
 DECLARE @pos INT

 WHILE CHARINDEX(@delim, @stringToSplit) > 0
 BEGIN
  SELECT @pos  = CHARINDEX(@delim, @stringToSplit)  
  SELECT @value = SUBSTRING(@stringToSplit, 1, @pos - 1)

  INSERT INTO @returnList 
  SELECT @value

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos + LEN(@delim), LEN(@stringToSplit) - @pos)
 END

 INSERT INTO @returnList
 SELECT @stringToSplit

 RETURN
END
GO

এবং এটি ব্যবহার করতে:

SELECT * FROM dbo.splitstring('test1 test2 test3', ' ');

(এসকিউএল সার্ভার ২০০৮ আর 2 এ পরীক্ষিত)

সম্পাদনা: সঠিক পরীক্ষার কোড


0

/ *

উত্তর টি-এসকিউএল বিভক্ত স্ট্রিং
নিকট থেকে উত্তর উপর ভিত্তি করে অ্যান্ডি রবিনসন এবং AviG
উন্নত কার্যকারিতা সুত্র: SQL সার্ভার মধ্যে শূণ্যস্থান trailing সহ না LEN এর ফাংশন
এই 'ফাইল' উভয় একটি markdown ফাইল এবং একটি SQL ফাইল হিসাবে টিকে বৈধ হতে হবে


*/

    CREATE FUNCTION dbo.splitstring ( --CREATE OR ALTER
        @stringToSplit NVARCHAR(MAX)
    ) RETURNS @returnList TABLE ([Item] NVARCHAR (MAX))
    AS BEGIN
        DECLARE @name NVARCHAR(MAX)
        DECLARE @pos BIGINT
        SET @stringToSplit = @stringToSplit + ','             -- this should allow entries that end with a `,` to have a blank value in that "column"
        WHILE ((LEN(@stringToSplit+'_') > 1)) BEGIN           -- `+'_'` gets around LEN trimming terminal spaces. See URL referenced above
            SET @pos = COALESCE(NULLIF(CHARINDEX(',', @stringToSplit),0),LEN(@stringToSplit+'_')) -- COALESCE grabs first non-null value
            SET @name = SUBSTRING(@stringToSplit, 1, @pos-1)  --MAX size of string of type nvarchar is 4000 
            SET @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, 4000) -- With SUBSTRING fn (MS web): "If start is greater than the number of characters in the value expression, a zero-length expression is returned."
            INSERT INTO @returnList SELECT @name --additional debugging parameters below can be added
            -- + ' pos:' + CAST(@pos as nvarchar) + ' remain:''' + @stringToSplit + '''(' + CAST(LEN(@stringToSplit+'_')-1 as nvarchar) + ')'
        END
        RETURN
    END
    GO

/*

পরীক্ষার কেসগুলি: উপরে "বর্ধিত কার্যকারিতা" হিসাবে উল্লেখ করা URL দেখুন

SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,,b')

Item | L
---  | ---
a    | 1
     | 0
b    | 1

SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,,')

Item | L   
---  | ---
a    | 1
     | 0
     | 0

SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,, ')

Item | L   
---  | ---
a    | 1
     | 0
     | 1

SELECT *,LEN(Item+'_')-1 'L' from splitstring('a,, c ')

Item | L   
---  | ---
a    | 1
     | 0
 c   | 3

* /


সম্মানের জন্য ফিরে রোল "এই 'ফাইলটি একটি মার্কডাউন ফাইল এবং একটি এসকিউএল ফাইল উভয়েরই হিসাবে বৈধ হওয়া উচিত"
এমপ্যাগ

-1
ALTER FUNCTION [dbo].func_split_string
(
    @input as varchar(max),
    @delimiter as varchar(10) = ";"

)
RETURNS @result TABLE
(
    id smallint identity(1,1),
    csv_value varchar(max) not null
)
AS
BEGIN
    DECLARE @pos AS INT;
    DECLARE @string AS VARCHAR(MAX) = '';

    WHILE LEN(@input) > 0
    BEGIN           
        SELECT @pos = CHARINDEX(@delimiter,@input);

        IF(@pos<=0)
            select @pos = len(@input)

        IF(@pos <> LEN(@input))
            SELECT @string = SUBSTRING(@input, 1, @pos-1);
        ELSE
            SELECT @string = SUBSTRING(@input, 1, @pos);

        INSERT INTO @result SELECT @string

        SELECT @input = SUBSTRING(@input, @pos+len(@delimiter), LEN(@input)-@pos)       
    END
    RETURN  
END

-1

আপনি এই ফাংশনটি ব্যবহার করতে পারেন:

        CREATE FUNCTION SplitString
        (    
           @Input NVARCHAR(MAX),
           @Character CHAR(1)
          )
            RETURNS @Output TABLE (
            Item NVARCHAR(1000)
          )
        AS
        BEGIN

      DECLARE @StartIndex INT, @EndIndex INT
      SET @StartIndex = 1
      IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
      BEGIN
            SET @Input = @Input + @Character
      END

      WHILE CHARINDEX(@Character, @Input) > 0
      BEGIN
            SET @EndIndex = CHARINDEX(@Character, @Input)

            INSERT INTO @Output(Item)
            SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)

            SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
      END

      RETURN
END
GO

-1

@ অভিগের প্রতি সমস্ত শ্রদ্ধার সাথে এটি সমস্ত টোকেনকে পুরোপুরি ফিরিয়ে দেওয়ার জন্য তাঁর তৈরি ফাংশনের বাগ ফ্রি সংস্করণ।

IF EXISTS (SELECT * FROM sys.objects WHERE type = 'TF' AND name = 'TF_SplitString')
DROP FUNCTION [dbo].[TF_SplitString]
GO

-- =============================================
-- Author:  AviG
-- Amendments:  Parameterize the delimeter and included the missing chars in last token - Gemunu Wickremasinghe
-- Description: Tabel valued function that Breaks the delimeted string by given delimeter and returns a tabel having split results
-- Usage
-- select * from   [dbo].[TF_SplitString]('token1,token2,,,,,,,,token969',',')
-- 969 items should be returned
-- select * from   [dbo].[TF_SplitString]('4672978261,4672978255',',')
-- 2 items should be returned
-- =============================================
CREATE FUNCTION dbo.TF_SplitString 
( @stringToSplit VARCHAR(MAX) ,
  @delimeter char = ','
)
RETURNS
 @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

    DECLARE @name NVARCHAR(255)
    DECLARE @pos INT

    WHILE LEN(@stringToSplit) > 0
    BEGIN
        SELECT @pos  = CHARINDEX(@delimeter, @stringToSplit)


        if @pos = 0
        BEGIN
            SELECT @pos = LEN(@stringToSplit)
            SELECT @name = SUBSTRING(@stringToSplit, 1, @pos)  
        END
        else 
        BEGIN
            SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)
        END

        INSERT INTO @returnList 
        SELECT @name

        SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
    END

 RETURN
END

-3

সহজতম পথ:

  1. এসকিউএল সার্ভার 2016 ইনস্টল করুন
  2. STRING_SPLIT https://msdn.microsoft.com/en-us/library/mt684588.aspx ব্যবহার করুন

এটি এক্সপ্রেস সংস্করণেও কাজ করে :)।


এসকিউএল সার্ভার 2016 (130) এ "সামঞ্জস্যতা স্তর" সেট করতে ভুলবেন না - ম্যানেজমেন্ট স্টুডিওতে, ডাটাবেস, বৈশিষ্ট্য / বিকল্প / সামঞ্জস্যতা স্তরে ডান ক্লিক করুন।
টমিনো

1
মূল পোস্টটি এসকিউএল ২০০৮ আর 2-এর জন্য বলেছে। এসকিউএল 2016 ইনস্টল করা কোনও বিকল্প নাও হতে পারে
শন গাভেট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.