このパラメーターがあります
@ID varchar = ‘1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20’
コンマ区切りの値を分割するために何かしたいのですが。
string_split
関数が機能せず、次のエラーが表示されます。
STRING_SPLIT関数は、互換性レベル130でのみ使用可能です
データベースを変更して互換性を130に設定しようとしましたが、この変更の許可がありません。
他のアプローチでは、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);
結果:
DATA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
例:
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;
データベースの互換性レベルを変更できない場合の@ Al3x_Mのポリフィルの少しのバリエーション:後で別のクエリで使用するために、値のリストを格納するためにTABLE
変数を使用します。
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
データベースの互換性レベルが1より低い場合、SQL ServerはSTRING_SPLIT
関数を見つけて実行できません。次のコマンドを使用して、データベースの互換性レベルを変更できます。
ALTER DATABASE DatabaseName SET COMPATIBILITY_LEVEL = 130
新しいAzure SQL Databasesでも、互換性レベル120がデフォルトになる場合があることに注意してください。
参考のため:
バージョン-最高の互換性レベル-最低の利用可能レベル
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
また、次のような構文も確認してください。
SELECT Value FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ');
別のアプローチは、WHILEで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