2012-02-29 4 views
1

J'ai collecté des valeurs à rechercher dans une colonne DB à l'intérieur d'une variable chaîne et j'essayais de le transmettre en tant que paramètre dans le SQL StoredProcedure.Passage du paramètre à l'instruction SQL IN

ALTER PROCEDURE [dbo].[InkDB] 
(
@ser nvarchar(255), 
@svt nvarchar(255) 
) 
AS 
SELECT DISTINCT Details from tbData WHERE (Name IN @svt AND [email protected]) 

Cela me donne un message syntax error near @svt tout en essayant d'exécuter la requête.

À partir de ma page Web, le paramètre a une valeur similaire à ('PersonA', 'Person B', 'Person C') en cours de transmission. Comment puis-je utiliser l'instruction IN dans ce cas?

+1

double possible de [SQL une Paramétrer clause?] (Http://stackoverflow.com/questions/337704/parameterizing-an-sql-in-clause) –

+0

Lié: http://stackoverflow.com/q/608562/55209 –

Répondre

0

C'est une erreur courante - vous passez une seule valeur (expression) de type string à l'opérateur IN mais IN attend une liste de valeurs séparées par des virgules (expressions) et pas une seule variable de chaîne. Ce que vous devez faire ici est d'avoir une fonction qui diviserait le paramètre donné en plusieurs valeurs basées sur un délimiteur donné, puis utiliserait cette liste avec le mot clé IN. Par exemple,

SELECT DISTINCT Details from tbData WHERE Name IN (SELECT Val FROM dbo.efn_Split(@svt, ',')) AND [email protected] 

efn_Split est une fonction de la valeur de la table qui va diviser des valeurs séparées par des virgules dans une table. Voir ces différentes questions ainsi pour la mise en œuvre de cette fonction:
Split function equivalent in T-SQL?
How to split string using delimiter char using T-SQL?

Une autre alternative est de construire l'instruction SQL et exécuter avec sp_executesql.

-1

IN a besoin d'être comme suit:

... IN (@ param1, @ param2, ...)

Donc, vous devez faire:

SELECT DISTINCT Details from tbData WHERE Name IN (@svt) AND [email protected] 

Mise à jour:

L'instruction de procédure alter que vous avez fournie dans votre question est syntaxiquement incorrecte. Ma réponse fournit la syntaxe correcte pour écrire l'instruction et elle compile. En relisant votre question, je vois que vous avez en fait deux problèmes. La première était une erreur de syntaxe et la seconde transmettait une liste délimitée par des virgules dans un seul paramètre.

La réponse est simplement que vous ne pouvez pas fournir une liste de valeurs séparées par des virgules au moment de l'exécution dans un seul paramètre de type chaîne utilisé dans la clause IN (...). Maintenant, sur ce deuxième point, je dirais que ce n'est pas une bonne approche de conception/programmation du problème, mais cela peut être fait en utilisant SQL dynamique ou en analysant chaque valeur du paramètre chaîne, les stocker dans une table temporaire puis réviser votre requête pour joindre à cela, ou utiliser un (ou utiliser une fonction de valeur table et stocker les éléments analysés là, où il peut être interrogé

Voici la syntaxe corrigée pour votre code, mais cela ne résoudrait pas le problème. deuxième aspect du passage d'une chaîne contenant une liste de valeurs séparées par des virgules, ce qui pourrait être résolu comme je l'ai décrit ci-dessus

Pour l'erreur de syntaxe, vous pouvez d'abord créer une table fictive pour tester votre code. La table de base de données doit avoir une clé primaire.Ceci est strictement une table factice pour tester la déclaration:

CREATE TABLE TbData ( Nom nvarchar (255), Détails nvarchar (255), Adresse nvarchar (255) );

Ensuite, vous pouvez créer la procédure initiale stockée:

CREATE PROCEDURE test ( @ser nvarchar (255), @svt nvarchar (255) ) AS BEGIN SELECT DISTINCT Détails DE tbData OÙ Nom IN (@ser) et adresse = @svt FIN

Et enfin, exécutez l'instruction de procédure stockée alter vous avait posé des questions sur:

ALTER PROCEDURE test ( @ser nvarchar (255), @svt nvarchar (255) ) AS BEGIN SELECT DISTINCT Détails DE tbData OU Nom IN (@ser) et adresse = @svt FIN

+0

L'exécution de la partie where de l'instruction de requête à 'WHERE (Name IN (@svt) AND Address = @ ser)' me donne une erreur 'syntaxe incorrecte près de ')''. – Cipher

+0

Elan - L'avez-vous déjà essayé? –

+0

Je pense que vous avez mal compris la question. '@ ser' contient une chaîne de valeurs séparées par des virgules comme' PersonA, PersonB, PersonC' et OP veut que les lignes correspondent à l'une des valeurs. Votre requête renverra uniquement des valeurs où le nom correspond exactement à la chaîne entière. –

1

Requête dynamique

Alter procedure test 
(
    @ser nvarchar(255), 
    @svt nvarchar(255) 
) 
AS 
BEGIN 
    declare @sql nvarchar(Max) 

    Set @sql='SELECT DISTINCT semester_code from mst_paper WHERE course_code IN ('[email protected]+') AND branch_code='[email protected]+'' 

    exec sp_executesql @sql 
END 
+1

Je ne recommanderais pas cette approche car elle est susceptible de subir une injection SQL (à moins que le code d'appel du cours n'assure le bon fonctionnement du paramètre @svt)! – VinayC

+0

Non, cela ne peut pas provoquer l'injection SQL. Raison d'être - C'est un proc stocké avec des paramètres. Donc, définitivement, les paramètres SQL seront utilisés à partir du langage (C# ou VB.Net). Droite ? – Pankaj

+0

@PankajGarg, si le paramètre '@ svt' ou @ser est composé en concaténant une entrée d'utilisateur, alors un utilisateur malveillant peut injecter n'importe quel SQL dans la requête! – VinayC

2

je le faire avec XML. Impossible de trouver cette solution dans la question en double donc je l'ajoute ici.

Votre SP pourrait ressembler à ceci:

alter procedure InkDB 
    @ser nvarchar(255), 
    @svt xml 
as 

declare @T table 
(
    Name nvarchar(50) 
) 

insert into @T 
select T.N.value('.', 'nvarchar(50)') 
from @svt.nodes('/N') as T(N) 

select distinct Details 
from tbData 
where Name in (select Name from @T) and 
     [email protected] 

Et vous appelleriez comme ça.

exec InkDB '', '<N>PersonA</N><N>PersonB</N>' 
+0

Que signifie T.N.value ici? Aimeriez-vous fournir un lien qui contient la description de ses détails? – Pankaj

+0

+1 Cela réduit le code pour les valeurs séparées par des virgules en utilisant "Table Valued Function". – Pankaj

+0

@PankajGarg - '.nodes' et' .value' sont utilisés pour analyser et déchiqueter XML dans SQL Server. Vous pouvez en lire plus à ce sujet ici. [Introduction à XQuery dans SQL Server 2005] (http://msdn.microsoft.com/en-US/library/ms345122%28v=sql.90%29.aspx) –

Questions connexes