J'ai ce paramètre
@ID varchar = ‘1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20’
Je veux faire quelque chose pour diviser les valeurs séparées par des virgules.
La fonction string_split
ne fonctionne pas et j'obtiens cette erreur:
La fonction STRING_SPLIT est disponible uniquement sous le niveau de compatibilité 130
et j'essaie de modifier ma base de données et de définir la compatibilité sur 130 mais je ne dispose pas de l'autorisation nécessaire pour ce changement.
Une autre approche consiste à utiliser aussi la méthode XML
avec CROSS APPLY
pour fractionner vos données séparées par des virgules:
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);
Résultat :
DATA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Exemple :
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;
Une petite variation du polyfill de @ Al3x_M, quand il n'est pas possible de changer le niveau de compatibilité de la base de données: J'utilise une variable TABLE
pour stocker la liste de valeurs, pour pouvoir les utiliser plus tard dans une autre requête:
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
Si le niveau de compatibilité de votre base de données est inférieur à 130 , SQL Server ne pourra pas trouver et exécuter la fonction STRING_SPLIT
. Vous pouvez modifier un niveau de compatibilité de la base de données à l'aide de la commande suivante:
ALTER DATABASE DatabaseName SET COMPATIBILITY_LEVEL = 130
Notez que le niveau de compatibilité 120 peut être défini par défaut, même dans les nouvelles bases de données SQL Azure.
Pour référence:
Version - Niveau de compatibilité le plus élevé - Niveau disponible le plus bas
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
Vérifiez également votre syntaxe, comme suit:
SELECT Value FROM STRING_SPLIT('Lorem ipsum dolor sit amet.', ' ');
Une autre approche consisterait à utiliser CHARINDEX et SUBSTRING dans un 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