2009-02-11 4 views
8

Existe-t-il un moyen de transmettre le tableau de valeurs à la section IN d'un SP en tant que paramètre unique pour SQL Server 2005?SQL Server SP - paramètre Pass pour la liste de tableaux "IN"?

Ex: Sélectionnez * à partir MyTable où ID IN (@MyValueArray)

+0

double: http://stackoverflow.com/questions/144550/sql-server- dynamic-where-clause – JoshBerke

+0

Dupliquer: http://stackoverflow.com/questions/337704/parameterizing-a-sql-in-clause – JoshBerke

+1

duplication possible de [procédure stockée T-SQL qui accepte plusieurs valeurs Id] (http: // stackoverflow.com/questions/43249/t-sql-stored-procedure-that-accepts-multiple-id-values) –

Répondre

5

En 2005 et plus tôt vous ne pouvez pas passer un tableau en tant que paramètre à une procédure stockée mais pour émuler passer cette fonctionnalité dans une liste séparée par des virgules des ID en tant que paramètre VARCHAR. Vous devrez ensuite analyser cette liste en ajoutant chaque identifiant à une table de variables. Ensuite, utilisez IN sur le résultat de la table. Ce n'est pas une solution élégante, mais c'est le meilleur que vous pouvez faire.

DECLARE @List TABLE (ID INT) 

INSERT @List VALUES ('123') 
INSERT @List VALUES ('12') 

SELECT * 
FROM 
    MyTable 
WHERE 
    MyTableID IN (SELECT ID FROM @List) 

Ce mieux est accompli en créant une fonction qui prend dans une liste des ids comme une chaîne et retourne votre liste d'ID comme une table.

IF EXISTS(
    SELECT * 
    FROM sysobjects 
    WHERE name = 'ParseIDArray') 
BEGIN 
    DROP FUNCTION ParseIDArray 
END 
GO 

CREATE FUNCTION [dbo].[ParseIDArray] (@IDList VARCHAR(8000)) 
RETURNS 
    @IDListTable TABLE (ID INT) 
AS 
BEGIN 

    DECLARE 
     [email protected] VARCHAR(100), 
     @LastCommaPosition INT, 
     @NextCommaPosition INT, 
     @EndOfStringPosition INT, 
     @StartOfStringPosition INT, 
     @LengthOfString INT, 
     @IDString VARCHAR(100), 
     @IDValue INT 

    --SET @IDList = '11,12,113' 

    SET @LastCommaPosition = 0 
    SET @NextCommaPosition = -1 

    IF LTRIM(RTRIM(@IDList)) <> '' 
    BEGIN 

     WHILE(@NextCommaPosition <> 0) 
     BEGIN 

      SET @NextCommaPosition = CHARINDEX(',',@IDList,@LastCommaPosition + 1) 

      IF @NextCommaPosition = 0 
       SET @EndOfStringPosition = LEN(@IDList) 
      ELSE 
       SET @EndOfStringPosition = @NextCommaPosition - 1 

      SET @StartOfStringPosition = @LastCommaPosition + 1 
      SET @LengthOfString = (@EndOfStringPosition + 1) - @StartOfStringPosition 

      SET @IDString = SUBSTRING(@IDList,@StartOfStringPosition,@LengthOfString)     

      IF @IDString <> '' 
       INSERT @IDListTable VALUES(@IDString) 

      SET @LastCommaPosition = @NextCommaPosition 

     END --WHILE(@NextCommaPosition <> 0) 

    END --IF LTRIM(RTRIM(@IDList)) <> '' 

    RETURN 

ErrorBlock: 

    RETURN 

END --FUNCTION 

Voici un exemple de création d'une procédure stockée qui prend dans une liste d'ID en utilisant cette fonction

IF EXISTS (SELECT * FROM sysobjects WHERE name = 'TestArrayParameter') 
BEGIN 
    DROP PROCEDURE TestArrayParameter 
END 
GO 



CREATE PROCEDURE TestArrayParameter 
    @ArrayParameter VARCHAR(8000) 
AS 
BEGIN 


    SELECT * 
    FROM TestTable123 
    WHERE TestTblID IN (SELECT ID FROM [dbo].[ParseIDArray](@ArrayParameter)) 

    -- OR BETTER 

    SELECT * 
    FROM 
     TestTable123 test 
     INNER JOIN [dbo].[ParseIDArray](@ArrayParameter) list 
     ON list.ID = test.TestTblID 

END 
GO 

CREATE TABLE TestTable123 (TestTblID INT, TestTblVal VARCHAR(50)) 

INSERT TestTable123 VALUES (3,'Three') 
INSERT TestTable123 VALUES (25,'Twenty Five') 
INSERT TestTable123 VALUES (100,'One Hundred') 

DECLARE @IDList VARCHAR(8000) 

SET @IDList = '25,100' 

EXEC TestArrayParameter @IDList 

DROP TABLE TestTable123 
Questions connexes