Je vais essayer d'éviter les boucles et insérer les lignes directement à partir de votre liste par des virgules.
Utilisez un paramètre de valeurs de table (nouveau dans SQl Server 2008). Mis en place en créant le type de paramètre réel de la table:
CREATE TYPE IntTableType AS TABLE (ID INTEGER PRIMARY KEY)
Votre procédure serait alors:
Create Procedure up_TEST
@Ids IntTableType READONLY
AS
SELECT *
FROM ATable a
WHERE a.Id IN (SELECT ID FROM @Ids)
RETURN 0
GO
si vous ne pouvez pas utiliser les paramètres de valeur de table, voir: "Arrays and Lists in SQL Server 2005 and Beyond, When Table Value Parameters Do Not Cut it" by Erland Sommarskog, alors il y a plusieurs façons de diviser une chaîne dans SQL Server. Cet article couvre les PROs et CONs de presque toutes les méthodes. en général, vous devez créer une fonction de séparation. Voici comment une fonction split peut être utilisé pour insérer des lignes:
INSERT INTO YourTableA (colA)
SELECT
b.col1
FROM dbo.yourSplitFunction(@Parameter) b
I prefer the number table approach to split a string in TSQL mais il existe de nombreuses façons de diviser les chaînes dans SQL Server, voir le lien précédent, ce qui explique les avantages et les inconvénients de chacun.
Pour la méthode de table de nombres au travail, vous devez faire une configuration de table de temps, ce qui va créer 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 des numéros est mis en place , créez cette fonction split:
CREATE FUNCTION [dbo].[FN_ListToTable]
(
@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 not return empty rows
----------------
SELECT
ListValue
FROM (SELECT
LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue
FROM (
SELECT @SplitOn + @List + @SplitOn AS List2
) AS dt
INNER JOIN Numbers n ON n.Number < LEN(dt.List2)
WHERE SUBSTRING(List2, number, 1) = @SplitOn
) dt2
WHERE ListValue IS NOT NULL AND ListValue!=''
);
GO
Vous pouvez maintenant facilement découper une chaîne CSV dans une table et se joindre à elle:
Create Procedure up_TEST
@Ids VARCHAR(MAX)
AS
SELECT * FROM ATable a
WHERE a.Id IN (SELECT ListValue FROM dbo.FN_ListToTable(',',@Ids))
GO
ou insérer des lignes de ce:
Create Procedure up_TEST
@Ids VARCHAR(MAX)
,@OtherValue varchar(5)
AS
INSERT INTO YourTableA
(colA, colB, colC)
SELECT
ListValue, @OtherValue, GETDATE()
FROM dbo.FN_ListToTable(',',@Ids)
GO
Si vous utilisez SQL Server 2008 et au-dessus, vous devriez regarder dans l'utilisation des paramètres de valeur de table au lieu de tricherie de valeur séparée par des virgules. – Oded
Est-ce que l'une des réponses données vous a donné une solution? –