SQL Server 2012中的STRING_SPLIT

Moh*_*Moh 11 sql split sql-server-2012

我有这个参数

@ID varchar = ‘1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20’ 
Run Code Online (Sandbox Code Playgroud)

我想做一些事情来分割逗号分隔值.

string_split功能不起作用,我收到此错误:

STRING_SPLIT功能仅在兼容级别130下可用

我尝试更改我的数据库并将兼容性设置为130,但我没有此更改的权限.

Yog*_*rma 19

其他方法也是使用XML方法CROSS APPLY来分割逗号分隔数据:

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);
Run Code Online (Sandbox Code Playgroud)

结果:

DATA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Run Code Online (Sandbox Code Playgroud)

示例:

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;
Run Code Online (Sandbox Code Playgroud)


Den*_*nis 9

基于Yogesh SharmaSalman A 的内联函数答案:

Create FUNCTION [dbo].[fn_split_string]
(
    @string    nvarchar(max),
    @delimiter nvarchar(max)
)
/*
    The same as STRING_SPLIT for compatibility level < 130
    https://docs.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-ver15
*/
RETURNS TABLE AS RETURN
(
    SELECT 
      --ROW_NUMBER ( ) over(order by (select 0))                            AS id     --  intuitive, but not correect
        Split.a.value('let $n := . return count(../*[. << $n]) + 1', 'int') AS id
      , Split.a.value('.', 'NVARCHAR(MAX)')                                 AS value
    FROM
    (
        SELECT CAST('<X>'+REPLACE(@string, @delimiter, '</X><X>')+'</X>' AS XML) AS String
    ) AS a
    CROSS APPLY String.nodes('/X') AS Split(a)
)
Run Code Online (Sandbox Code Playgroud)

例子:

DECLARE @ID NVARCHAR(300)= 'abc,d,e,f,g';
select * from fn_split_string(@ID,',')

-- If you need exactly string_split functionality (without id column):
select value from fn_split_string(@ID,',')
Run Code Online (Sandbox Code Playgroud)


小智 5

另一种方法是同时使用 CHARINDEX 和 SUBSTRING:

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;
Run Code Online (Sandbox Code Playgroud)