टी-एसक्यूएल स्प्लिट स्ट्रिंग


139

मेरे पास SQL ​​Server 2008 R2 स्तंभ है जिसमें एक स्ट्रिंग है जिसे मुझे अल्पविराम से विभाजित करने की आवश्यकता है। मैंने StackOverflow पर कई उत्तर देखे हैं लेकिन उनमें से कोई भी R2 में काम नहीं करता है। मैंने सुनिश्चित किया है कि मेरे पास किसी भी विभाजन फ़ंक्शन के उदाहरणों पर अनुमतियाँ हैं। किसी भी मदद की बहुत सराहना की।


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
CF_Maintainer

1
मैं कुछ सुधार मेरी GitHub पृष्ठ पर (परीक्षण मामलों समर्थन के साथ) पोस्ट यहाँ । मैं इसे इस स्टैक ओवरफ्लो थ्रेड में एक उत्तर के रूप में पोस्ट करूंगा जब मेरे पास "सुरक्षा" से अधिक के लिए पर्याप्त प्रतिनिधि होगा
एमपाग

8
हालांकि यह एक महान जवाब है, यह पुराना है ... प्रक्रियात्मक दृष्टिकोण (विशेष रूप से छोरों) से बचने के लिए कुछ हैं ... यह नए जवाबों को देखने के लिए लायक है ...
शन्नू

2
मैं पूरी तरह @Shnugo से सहमत हूं। लूपिंग स्प्लिटर काम करते हैं लेकिन बहुत धीमी गति से। इस sqlservercentral.com/articles/Tally+Table/72993 जैसा कुछ बेहतर है। कुछ अन्य उत्कृष्ट सेट आधारित विकल्प यहां देखे जा सकते हैं। sqlperformance.com/2012/07/t-sql-queries/split-strings
शॉन लैंग

61

पुनरावर्ती CTE और लूप के बजाय, किसी ने अधिक सेट-आधारित दृष्टिकोण पर विचार किया है? ध्यान दें कि यह फ़ंक्शन प्रश्न के लिए लिखा गया था, जो एसक्यूएल सर्वर 2008 पर आधारित था और सीमांकक परिसीमनकर्ता के रूप में था । SQL Server 2016 और उससे ऊपर (और संगतता स्तर 130 और ऊपर) में, 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( modelSQL सर्वर 2017 में 9,980 , अपने स्वयं के उपयोगकर्ता डेटाबेस में बहुत अधिक), तो आप संख्याओं को प्राप्त करने के लिए अन्य तरीकों का उपयोग कर सकते हैं, जैसे कि संख्याओं की अपनी तालिका बनाना । आप उन मामलों में भी पुनरावर्ती CTE का उपयोग कर सकते हैं जहां आप सिस्टम टेबल का उपयोग नहीं कर सकते हैं या अपना खुद का बना सकते हैं:

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

लेकिन आपको स्ट्रिंग्स> 100 वर्णों के लिए पुनरावृत्ति के साथ त्रुटियों से बचने के लिए बाहरी क्वेरी में जोड़ना होगा OPTION (MAXRECURSION 0)(या MAXRECURSION <longest possible string length if < 32768>)। यदि वह भी एक अच्छा विकल्प नहीं है, तो इस उत्तर को टिप्पणियों के रूप में देखें ।

(इसके अलावा, सीमांकक होना होगा NCHAR(<=1228)। फिर भी शोध क्यों।)

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


1
इस प्रक्रिया के लिए एक छोटा सा बग है, जहां स्ट्रिंग के अंत में एक शून्य मान होगा - जैसे कि '1,2, 4, 4' में - क्योंकि अंतिम मूल्य पार्स नहीं है। इस बग को ठीक करने के लिए, "WHERE नंबर <= LEN (@List)" को "WHERE नंबर <= LEN (@List) + 1" से बदलना चाहिए।
सिल्वेनएल

@SylvainL मुझे लगता है कि आप क्या व्यवहार चाहते हैं पर निर्भर करता है। मेरे अनुभव में, ज्यादातर लोग किसी भी अनुगामी अल्पविराम को अनदेखा करना चाहते हैं क्योंकि वे वास्तव में एक वास्तविक तत्व का प्रतिनिधित्व नहीं करते हैं (आपको रिक्त स्ट्रिंग की कितनी प्रतियां चाहिए)? वैसे भी, ऐसा करने का असली तरीका - यदि आप दूसरी कड़ी का पालन करेंगे - वैसे भी धीमी टी-एसक्यूएल में बड़े बदसूरत तारों को विभाजित करने के साथ खिलवाड़ करना है।
एरोन बर्ट्रेंड

1
जैसा कि आपने कहा है, ज्यादातर लोग किसी भी कमिंग ट्रेल्स को अनदेखा करना चाहते हैं, लेकिन अफसोस, सभी नहीं। मुझे लगता है कि इस मामले में क्या करना है यह निर्दिष्ट करने के लिए एक अधिक पूर्ण समाधान एक पैरामीटर जोड़ना होगा, लेकिन मेरी टिप्पणी यह ​​सुनिश्चित करने के लिए सिर्फ एक छोटी सी टिप्पणी है कि कोई भी इस संभावना के बारे में नहीं भूल सकता है, क्योंकि यह कई मामलों में काफी वास्तविक हो सकता है।
सिल्वेनएल

मेरा उस समारोह के साथ एक अजीब व्यवहार है। अगर मैं एक स्ट्रिंग को एक पैरामीटर के रूप में सीधे उपयोग करता हूं - यह काम करता है। यदि मेरे पास एक वर्चर है, तो यह नहीं है। आप आसानी से पुन: पेश कर सकते हैं: इन्वार्चर को varchar set invarchar = 'ta; aa; qq' के रूप में [dbo] से चुनें मूल्य घोषित करें। [स्प्लिटस्ट्रिंग] (invarchar, ';') 'dbo] से सेलेक्ट वैल्यू [स्प्लिटस्ट्रिंग] (' ta '; आ; क़्क़ ','; ')
पैट्रिक डेसजार्डिन

मुझे यह दृष्टिकोण पसंद है, लेकिन अगर वस्तुओं sys.all_objectsकी संख्या इनपुट स्ट्रिंग में वर्णों की संख्या से कम है तो यह स्ट्रिंग को छोटा कर देगी और मान गायब हो जाएंगे। चूंकि sys.all_objectsपंक्तियों को उत्पन्न करने के लिए बस एक हैक के रूप में उपयोग किया जा रहा है, तो ऐसा करने के लिए बेहतर तरीके हैं, जैसे यह उत्तर
पोर

56

अंत में एसक्यूएल सर्वर 2016 में इंतजार खत्म हो गया है, उन्होंने स्प्लिट स्ट्रिंग फंक्शन पेश किया है:STRING_SPLIT

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

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

यहां प्रदर्शन तुलना के साथ एक उत्कृष्ट लेख है: प्रदर्शन आश्चर्य और अनुमान: STRING_SPLIT


5
स्पष्ट रूप से उत्तर देते हैं कि अद्यतन सर्वर वाले लोगों के लिए स्ट्रिंग को कैसे विभाजित किया जाए, लेकिन हम में से जो अभी भी 2008 / 2008R2 पर अटक गए हैं, उन्हें यहां अन्य उत्तरों में से एक के साथ जाना होगा।
मपग

2
आपको अपने डेटाबेस में संगतता स्तर पर एक नज़र डालने की आवश्यकता है। यदि यह 130 से कम है तो आप STRING_SPLIT फ़ंक्शन का उपयोग नहीं कर पाएंगे।
लुइस टेइजन

वास्तव में, यदि संगतता 130 नहीं है और आप 2016 (या Azure SQL) चला रहे हैं, तो आप 130 का उपयोग करके संगतता सेट कर सकते हैं: ALTER DATABASE DatabaseName SET
COMPATIBILITY_LEVEL

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

2. एक तालिका से पंक्तियों में परिवर्तित करना जिसमें प्रत्येक CSV पंक्ति के लिए एक ID हो

स्रोत टेबल

 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
यह वह नहीं है जिसके बारे में सवाल है। ओपी का मान 23 234,542,23 ’है और वे इसे तीन पंक्तियों में विभाजित करना चाहते हैं ... पहली पंक्ति: 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" बन जाएगा | "ए" अर्थात "एबीसी, एबीसी, एबीसी" "एबीसी" बन जाएगा "एबीसी" | "एबी"
Microsoft डेवलपर

उस मुद्दे को संबोधित करने के +1लिए SELECT @pos = LEN(@stringToSplit)प्रकट होता है। हालाँकि, जब तक आप SUBSTRING के तीसरे पैरामीटर को नहीं जोड़ते SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)हैं, Invalid length parameter passed to the LEFT or SUBSTRING functionतब तक वापस आ जाएगा +1। या आप उस असाइनमेंट को बदल सकते हैंSET @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, 4000) --MAX len of nvarchar is 4000
mpag

1
मैं कुछ सुधार मेरी GitHub पृष्ठ पर (परीक्षण मामलों समर्थन के साथ) पोस्ट यहाँ । मैं इसे इस स्टैक ओवरफ्लो थ्रेड में एक उत्तर के रूप में पोस्ट करूंगा जब मेरे पास "सुरक्षा" से अधिक के लिए पर्याप्त प्रतिनिधि होगा
एमपाग

मैंने भी टेरी द्वारा ऊपर बताई गई बात को नोट किया है। लेकिन @AviG द्वारा दिया गया तर्क इतना अच्छा है कि यह टोकन की लंबी सूची के लिए बीच में विफल नहीं होता है। सत्यापित करने के लिए इस परीक्षण कॉल का प्रयास करें (यह कॉल 969 टोकन वापस करना चाहिए) dbo.splitstring ('token1, token2 ,,,,,,, token969' से * चुनें) फिर मैंने उसी के परिणामों की जांच करने के लिए mpag द्वारा दिए गए कोड की कोशिश की ऊपर कॉल करें और पाया कि यह केवल 365 टोकन वापस कर सकता है। अंत में मैंने ऊपर AVIG द्वारा कोड तय किया और नीचे दिए गए नए उत्तर के रूप में बग फ्री फ़ंक्शन को पोस्ट किया क्योंकि यहाँ टिप्पणी केवल सीमित पाठ की अनुमति देती है। इसे आज़माने के लिए मेरे नाम के तहत उत्तर की जाँच करें।
जेमुनु आर विक्रमसिंघे

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निषिद्ध वर्ण हैं ... मैंने अभी इस मुद्दे को दूर करने के लिए एक उत्तर पोस्ट किया है ।
शन्नू

मैं आपकी प्रतिक्रिया को बढ़ा रहा हूं क्योंकि आपका स्थान सीमांकक के रूप में अंतरिक्ष के साथ काम करता है और सबसे ज्यादा मतदान करता है
KMC

3

निषिद्ध वर्णों के मामले में एक्सएमएल तत्वों के साथ अक्सर उपयोग किया जाने वाला दृष्टिकोण। यह किसी भी तरह के चरित्र के साथ इस पद्धति का उपयोग करने के लिए एक दृष्टिकोण है, यहां तक ​​कि सीमोलोन को सीमांकक के रूप में भी।

चाल है, पहले 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) की अल्पविराम वाली सूची होती है, जिसे मैं एक तालिका के रूप में उपयोग करने के लिए एक अन्य तालिका में सम्मिलित करना चाहता हूं जिसमें 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

यदि आपको न्यूनतम कोड वाले सामान्य मामलों के लिए त्वरित तदर्थ समाधान की आवश्यकता है, तो यह पुनरावर्ती CTE टू-लाइनर करेगा:

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

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

संपादित करें (Shnugo द्वारा)

यदि आप एक काउंटर जोड़ते हैं, तो आपको सूची के साथ एक स्थिति सूचकांक मिलेगा:

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','%[/,]%');

परिणाम इस तरह दिखता है

stringa stringb 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

यहां एक उदाहरण है जिसे आप फ़ंक्शन के रूप में उपयोग कर सकते हैं या आप एक ही तर्क को प्रक्रिया में रख सकते हैं। --SELECT * से [dbo] .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

एक पुनरावर्ती 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

यह एंडी रॉबर्टसन के जवाब पर आधारित है, मुझे अल्पविराम के अलावा एक सीमांकक की आवश्यकता थी।

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', ' ');

(SQL Server 2008 R2 पर परीक्षण किया गया)

EDIT: सही परीक्षण कोड


0

/ *

करने के लिए उत्तर T-SQL विभाजन स्ट्रिंग
से जवाब के आधार पर एंडी रॉबिन्सन और AviG
बढ़ी कार्यक्षमता रेफरी: एसक्यूएल सर्वर में रिक्त स्थान अनुगामी सहित नहीं 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

* /


सम्मान के लिए लुढ़का वापस "यह 'फ़ाइल' दोनों एक markdown फ़ाइल और एक SQL फ़ाइल के रूप में मान्य होना चाहिए"
mpag

-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

@AviG के लिए पूरे सम्मान के साथ, यह फंक्शन का बग फ्री वर्जन है, जो सभी टोकन को पूरा करने के लिए उनके द्वारा तैयार किया गया है।

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. SQL सर्वर 2016 स्थापित करें
  2. STRING_SPLIT https://msdn.microsoft.com/en-us/library/mt684588.aspx का उपयोग करें

यह एक्सप्रेस संस्करण में भी काम करता है :)।


SQL सर्वर 2016 (130) के लिए "संगतता स्तर" सेट करने के लिए मत भूलना - प्रबंधन स्टूडियो में, डेटाबेस, गुण / विकल्प / संगतता स्तर पर राइट क्लिक करें।
टोमिनो

1
SQL 2008 R2 के लिए मूल पोस्ट ने कहा। SQL 2016 इंस्टॉल करना एक विकल्प नहीं हो सकता है
Shawn Gavett
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.