2010-02-03 5 views
2

je dois formater une chaîne et le transmettre dans en tant que paramètre pour une SQL clause telle que:Mise en forme d'une chaîne pour une SQL à l'article

Select * from Table Where X In (@param1)

La chaîne littérale qui est passé en tant param ressemble à ceci:

"Item1, Item2, Item3"

cela ne semble pas fonctionner. Aucune suggestion? Merci!

+0

Vous ne pouvez pas faire cela avec la liaison de paramètre, malheureusement. Si c'est SQL Server, vous pouvez essayer de passer un document XML, vous pouvez faire un INSERT SELECT sur. –

+0

J'ai trouvé la solution ici: http://www.codeproject.com/KB/database/splitparameterstring.aspx, cela fait exactement ce dont j'avais besoin, je ne sais pas si c'est la meilleure approche – monO

Répondre

1

Vous ne pouvez pas utiliser une chaîne avec l'opérateur in et attendre à l'analyser. Il va juste comparer la chaîne entière avec les valeurs.

Vous devez créer la requête dynamique, quelque chose comme:

declare @sql varchar(4000) 
set @sql = 'select * from Table where X in (' + @param1 + ')' 
exec @sql 

Vous devez formater les valeurs que vous envoyez dans le paramètre comme des chaînes:

"'Item1','Item2','Item3'" 

Notez que la Les valeurs de chaîne doivent s'échapper correctement en fonction de la saveur de SQL que vous utilisez. C'est très important, ou votre requête est largement ouverte pour les injections SQL.

0

Je ne suis pas sûr si c'est la meilleure réponse, mais vous pouvez analyser le param dans une fonction qui renvoie une table et sélectionnez dans cette table dans le cadre de votre clause in.

Ex.

DECLARE @param1 varchar(50) 
SET @param1 = 'Item1, Item2, Item3' 

--CREATE a Table-valued FUNCTION to split param into a table(dbo.f_split_comma_separated_string) 

Select * from Table Where X In (SELECT X FROM dbo.f_split_comma_separated_string(@param1)) 
0

voir my previous answer to this

c'est la meilleure source:

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

créer une fonction split, et l'utiliser comme:

SELECT 
    * 
    FROM YourTable y 
    INNER JOIN dbo.splitFunction(@Parameter) s ON y.ID=s.Value 

I prefer the number table approach

Pour que cette méthode fonctionne, vous devez effectuer cette configuration de la table une seule fois:

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:

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 facilement diviser une chaîne CSV dans une table et se joindre à elle:

select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,') 

SORTIE:

ListValue 
----------------------- 
1 
2 
3 
4 
5 
6777 

(6 row(s) affected) 

Votre peut passer dans une chaîne CSV dans une seule procédure et traiter les lignes pour les ID donnés:

SELECT 
    y.* 
    FROM YourTable y 
     INNER JOIN dbo.FN_ListToTable(',',@GivenCSV) s ON y.ID=s.ListValue 

Cela utilisera un index sur y.ID