web-dev-qa-db-de.com

STRING_SPLIT in SQL Server 2012

Ich habe diesen Parameter

@ID varchar = ‘1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20’ 

Ich möchte etwas tun, um die durch Kommas getrennten Werte aufzuteilen.

Die string_split-Funktion funktioniert nicht und ich erhalte folgende Fehlermeldung:

Die Funktion STRING_SPLIT ist nur unter dem Kompatibilitätsgrad 130 verfügbar

ich versuche, meine Datenbank zu ändern und die Kompatibilität auf 130 zu setzen, aber ich habe keine Berechtigung für diese Änderung. 

5
Moh

Ein anderer Ansatz ist auch die XML-Methode mit CROSS APPLY, um Ihre durch Kommas getrennten Daten zu teilen:

SELECT Split.a.value('.', 'NVARCHAR(MAX)') DATA
FROM
(
    SELECT CAST('<X>'+REPLACE(@ID, ',', '</X><X>')+'</X>' AS XML) AS String
) AS A
CROSS APPLY String.nodes('/X') AS Split(a);

Ergebnis:

DATA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Beispiel:

DECLARE @ID NVARCHAR(300)= '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20';
DECLARE @Marks NVARCHAR(300)= '0,1,2,5,8,9,4,6,7,3,5,2,7,1,9,4,0,2,5,0';
DECLARE @StudentsMark TABLE
(id    NVARCHAR(300),
 marks NVARCHAR(300)
); 
--insert into @StudentsMark 
;WITH CTE
     AS (
     SELECT Split.a.value('.', 'NVARCHAR(MAX)') id,
            ROW_NUMBER() OVER(ORDER BY
                             (
                                 SELECT NULL
                             )) RN
     FROM
     (
         SELECT CAST('<X>'+REPLACE(@ID, ',', '</X><X>')+'</X>' AS XML) AS String
     ) AS A
     CROSS APPLY String.nodes('/X') AS Split(a)),
     CTE1
     AS (
     SELECT Split.a.value('.', 'NVARCHAR(MAX)') marks,
            ROW_NUMBER() OVER(ORDER BY
                             (
                                 SELECT NULL
                             )) RN
     FROM
     (
         SELECT CAST('<X>'+REPLACE(@Marks, ',', '</X><X>')+'</X>' AS XML) AS String
     ) AS A
     CROSS APPLY String.nodes('/X') AS Split(a))
     INSERT INTO @StudentsMark
            SELECT C.id,
                   C1.marks
            FROM CTE C
                 LEFT JOIN CTE1 C1 ON C1.RN = C.RN;
SELECT *
FROM @StudentsMark;
12
Yogesh Sharma

Eine kleine Variation von @ Al3x_Ms Polyfill, wenn der Kompatibilitätsgrad der Datenbank nicht geändert werden kann: Ich verwende eine Variable TABLE, um die Werteliste zu speichern, um sie später in einer anderen Abfrage verwenden zu können:

DECLARE @IDs VARCHAR(500);
SET @IDs = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,2a0' ;

declare @list TABLE (id int);
DECLARE @Number int, @idx int
DECLARE @charSpliter CHAR;

SET @charSpliter = ','
SET @IDs = @IDs + @charSpliter;
set  @idx = 0

WHILE (1 = 1)
    BEGIN
        set  @idx =  CHARINDEX(@charSpliter, @IDs)
        if (@idx is NULL or @idx <= 0) break;

        BEGIN TRY
        SET @Number = SUBSTRING(@IDs, 0, @idx)
        SET @IDs = SUBSTRING(@IDs, @idx + 1, LEN(@IDs))

        insert @list select convert(int, @Number)
    END TRY  
    BEGIN CATCH 
        break
    END CATCH  
END

-- @list available for the next query...
select * from  @list
0
Didier68

Wenn Ihre Datenbankkompatibilitätsstufe niedriger als 130 ist, kann SQL Server die STRING_SPLIT-Funktion nicht finden und ausführen. Sie können einen Kompatibilitätsgrad der Datenbank mit dem folgenden Befehl ändern:

ALTER DATABASE DatabaseName SET COMPATIBILITY_LEVEL = 130

Beachten Sie, dass der Kompatibilitätsgrad 120 auch in neuen Azure SQL-Datenbanken Standard sein kann.

Als Referenz:

Version - Höchste Kompatibilitätsstufe - Niedrigste verfügbare Stufe

SQL 2017 - 140 - 100
SQL 2016 - 130 - 100
SQL 2014 - 120 - 100
SQL 2012 - 110 - 90
SQL 2008 - 100 - 80
SQL 2005 - 90 - 80
SQL 2000 - 80 - 80

Überprüfen Sie auch Ihre Syntax: 

SELECT Value FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ');
0
hamzox

Ein anderer Ansatz wäre die Verwendung von CHARINDEX und SUBSTRING in einer WHILE:

DECLARE @IDs VARCHAR(500);
DECLARE @Number VARCHAR(500);
DECLARE @charSpliter CHAR;

SET @charSpliter = ','
SET @IDs = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20' + @charSpliter;

WHILE CHARINDEX(@charSpliter, @IDs) > 0
BEGIN
    SET @Number = SUBSTRING(@IDs, 0, CHARINDEX(@charSpliter, @IDs))
    SET @IDs = SUBSTRING(@IDs, CHARINDEX(@charSpliter, @IDs) + 1, LEN(@IDs))

    PRINT @Number

END
0
Al3x_M