Vous avez besoin d'un moyen de diviser et de traiter la chaîne dans TSQL, il existe de nombreuses façons de le faire. Cet article couvre les avantages et les inconvénients de presque toutes les méthodes :
Vous devez créer une fonction de fractionnement. Voici comment une fonction de fractionnement peut être utilisée :
SELECT
*
FROM YourTable y
INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value
Je préfère l'approche de la table numérique pour scinder une chaîne dans TSQL mais il existe de nombreuses façons de diviser des chaînes dans SQL Server, voir le lien précédent, qui explique les avantages et les inconvénients de chacun.
Pour que la méthode de la table des nombres fonctionne, vous devez effectuer cette configuration de table de temps unique, ce qui créera une table Numbers
qui contient des lignes de 1 à 10 000 :
SELECT TOP 10000 IDENTITY(int,1,1) AS Number
INTO Numbers
FROM sys.objects s1
CROSS JOIN sys.objects s2
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number)
Une fois la table Numbers configurée, créez cette fonction de fractionnement :
CREATE FUNCTION [dbo].[FN_ListToTableRows]
(
@SplitOn char(1) --REQUIRED, the character to split the @List string on
,@List varchar(8000)--REQUIRED, the list to split apart
)
RETURNS TABLE
AS
RETURN
(
----------------
--SINGLE QUERY-- --this will return empty rows, and row numbers
----------------
SELECT
ROW_NUMBER() OVER(ORDER BY number) AS RowNumber
,LTRIM(RTRIM(SUBSTRING(ListValue, number+1, CHARINDEX(@SplitOn, ListValue, number+1)-number - 1))) AS ListValue
FROM (
SELECT @SplitOn + @List + @SplitOn AS ListValue
) AS InnerQuery
INNER JOIN Numbers n ON n.Number < LEN(InnerQuery.ListValue)
WHERE SUBSTRING(ListValue, number, 1) = @SplitOn
);
GO
Vous pouvez maintenant facilement diviser une chaîne CSV en une table et la joindre. Pour accomplir votre tâche, si vous pouvez passer deux paramètres, une clé une valeur, puis créez votre procédure comme ceci :
CREATE PROCEDURE StoredProcedureName
(
@Params1 int
,@Array1 varchar(8000)
,@Params2 int
,@Array2 varchar(8000)
)
AS
DECLARE @YourTable table (col1 int, col2 int)
INSERT INTO @YourTable
(col1, col2)
SELECT
a1.ListValue, a2.ListValue
FROM dbo.FN_ListToTableRows(',',@Array1) a1
INNER JOIN dbo.FN_ListToTableRows(',',@Array2) a2 ON a1.RowNumber=a2.RowNumber
select * from @YourTable
GO
testez-le :
exec StoredProcedureName 17,'127,204,110,198',7,'162,170,163,170'
SORTIE :
(4 row(s) affected)
col1 col2
----------- -----------
127 162
204 170
110 163
198 170
(4 row(s) affected)
ou si vous souhaitez transmettre une seule paire de valeurs de clé de paramètre, utilisez quelque chose comme ceci :
CREATE PROCEDURE StoredProcedureName
(
@KeyValueList varchar(8000)
)
AS
DECLARE @YourTable table (RowKey varchar(500), RowValue varchar(500))
INSERT INTO @YourTable
(RowKey, RowValue)
SELECT
LEFT(y.ListValue,CHARINDEX(',',y.ListValue)-1),RIGHT(y.ListValue,LEN(y.ListValue)-CHARINDEX(',',y.ListValue))
FROM dbo.FN_ListToTableRows(';',@KeyValueList) y
SELECT * FROM @YourTable
GO
lancez-le :
exec StoredProcedureName 'a,5;b,BBB;abc,xyz'
SORTIE :
RowKey RowValue
------- -----------
a 5
b BBB
abc xyz
(3 row(s) affected)