2009-02-11 16 views
8

¿Hay alguna manera de pasar la matriz de valores a la sección IN de un SP como un solo parámetro para SQL Server 2005?SQL Server SP - ¿Pasa el parámetro para la lista de matriz "IN"?

Ex: SELECT * FROM MyTable donde ID IN (@MyValueArray)

+0

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

+0

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

+1

posible duplicado de [procedimiento almacenado de T-SQL que acepta múltiples valores de Id.] (http: // stackoverflow.com/questions/43249/t-sql-stored-procedure-that-accepts-multiple-id-values) –

Respuesta

5

En 2005 y anteriores no se puede pasar una matriz como un parámetro a un procedimiento almacenado, pero para emular este paso funcionalidad en una lista separada por comas de ID como un parámetro VARCHAR. A continuación, deberá analizar esta lista y agregar cada id a una tabla de variables. Luego usa IN en el resultado de la tabla. Esta no es una solución elegante, pero es lo mejor que puedes hacer.

DECLARE @List TABLE (ID INT) 

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

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

Esto se logra mejor mediante la creación de una función que toma en una lista de identificadores como una cadena y devuelve su lista de ID como una tabla.

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 

Aquí es un ejemplo de la creación de un procedimiento almacenado que realiza en una lista de ID de usar esta función

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 
Cuestiones relacionadas