Peut une procédure stockée ont des paramètres dynamiques à utiliser dans une clause « IN »?

StackOverflow https://stackoverflow.com/questions/977021

Question

Je veux exécuter une requête comme ceci:

 SELECT * FROM Studio WHERE Id IN (134, 144, 132, 138, 7432, 7543, 2566)

mais la quantité de Id passé à la clause IN est déterminée que lors de l'exécution.

Dois-je utiliser SQL dynamique ou peut-il être fait avec une procédure stockée?

Mise à jour: Si l'option est disponible, ce qui est le meilleur?

Merci.

Était-ce utile?

La solution

En fonction de votre version de SQL Server, vous pouvez le faire de deux façons différentes.

Pour Sql 2000/2005, vous pouvez utiliser un paramètre (type varchar) qui a une liste délimitée par des ID. Créer une UDF qui analyser le varchar et retourner une table contenant les éléments. Faites ensuite votre clause IN aller contre la table (à savoir ... IN (Select DE @ReturnTable)).

Voici un exemple de ce que le contenu de l'UDF ressemblerait à ceci: http://pietschsoft.com/post /2006/02/03/T-SQL-Parse-a-delimited-string.aspx

Pour SQL Server 2008, vous pouvez faire la même chose; Cependant, au lieu de passer dans un paramètre varchar vous pouvez simplement couper à la chasse et passer dans un paramètre de tableau. La clause IN aurait encore une sous-requête, mais cela fonctionnerait tout de même. Sinon, une fois que vous avez la table que vous pouvez juste faire une jointure interne et sur la nécessité de contourner la clause IN.

EDIT:. UDF ajoutée pour l'analyse d'une liaison de chaîne délimitée

Autres conseils

Solution décrite ici:

Les tableaux et les listes dans SQL Server 2005

Un texte SQL par Erland Sommarskog, MVP SQL Server

http://www.sommarskog.se/arrays-in-sql- 2005.html

Vous pouvez tout à fait faire dans une procédure stockée.

créer une table temporaire dans la procédure stockée et insérez les valeurs partagées sur les virgules ou tout delimiter faites ceci

SELECT * FROM Studio WHERE Id IN (select id from temptable)

Ensuite, supprimez la table.

Voici une UDF que je sers depuis MSSQL 2000. Je trouve cela quelque part -. Désolé, je ne me souviens pas où

En fait, vous pouvez faire une jointure sur l'UDF, où la première est la chaîne param délimitée, et le second est le param delimiter.

SELECT t1.somecolumn DE sometable t1 INNER JOIN dbo.Split (@delimitedVar, '') t2 = ON t1.ID t2.Element

CREATE FUNCTION [dbo].[Split]
(
@vcDelimitedString varchar(max),
@vcDelimiter varchar(100)
)
RETURNS @tblArray TABLE
   (
    ElementID smallint  IDENTITY(1,1), --Array index
    Element varchar(1000) --Array element contents
   )
AS
BEGIN
    DECLARE @siIndex smallint, @siStart smallint, @siDelSize smallint
    SET @siDelSize  = LEN(@vcDelimiter)
    --loop through source string and add elements to destination table array
    WHILE LEN(@vcDelimitedString) > 0
    BEGIN
        SET @siIndex = CHARINDEX(@vcDelimiter, @vcDelimitedString)
        IF @siIndex = 0
        BEGIN
            INSERT INTO @tblArray VALUES(@vcDelimitedString)
            BREAK
        END
        ELSE
        BEGIN
            INSERT INTO @tblArray VALUES(SUBSTRING(@vcDelimitedString, 1,@siIndex - 1))
            SET @siStart = @siIndex + @siDelSize
            SET @vcDelimitedString = SUBSTRING(@vcDelimitedString, @siStart , LEN(@vcDelimitedString) - @siStart + 1)
        END
    END
    RETURN
END

Dans SQL Server 2008, vous pouvez utiliser un paramètre valeur .

Dans SQL 2005, vous devez utiliser SQL dynamique, sauf si vous voulez passer la liste en XML et utiliser le traitement de XML dans la procédure de déchiqueter le retour XML dans une variable de table.

déclarer une table de @temp et de diviser les valeurs en elle. alors vous pouvez faire

select * from studio interne de rejoindre @temptable tb sur s.ID = tb.ID

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top