2010-11-04 12 views
2

Je suis en train de créer la clause WHERE suivante:instruction CASE avec IN dans la clause WHERE

AND CASE @SomePRarmeter 
WHEN 'this' THEN 
    user_id IN (SELECT * FROM dbo.func_Id1(@User)) 
WHEN 'that' THEN 
    user_id IN (SELECT user_id from dbo.func_Ids2(@OrgsForReporter) 
END 

Mais je reçois une erreur: syntaxe incorrecte près du mot-clé 'IN' (dans la première condition) , bien que séparément ces deux conditions fonctionnent. Quelle serait la bonne façon de faire fonctionner une telle déclaration?

Merci!

+0

Avez-vous essayé de mettre des parenthèses autour les 3ème et 5ème lignes? – jthg

+0

Comme cela - (user_id IN (SELECT * FROM dbo.func_getReportsToUserId (@User)))? Cela n'a pas fonctionné non plus, m'a donné la même erreur à propos de IN et ensuite à propos de ')' – Masha

+0

NM mon dernier commentaire. La clause THEN attend une valeur. L'expression IN n'évalue pas à une valeur. – jthg

Répondre

11

Essayez

AND (
    (@SomePRarmeter = 'this' AND user_id IN (SELECT * FROM dbo.func_Id1(@User))) 
    OR 
    (@SomePRarmeter = 'that' AND user_id IN user_id IN (SELECT user_id from dbo.func_Ids2(@OrgsForReporter))) 
) 
+1

C'est un bon, je vais essayer! – Masha

+2

+1 Beaucoup mieux qu'un cas compliqué! Peut-être changer le 'select *' en 'select user_id' (bien que cela ne devrait pas avoir d'importance si la fonction retourne une seule colonne) – Andomar

+0

Cela a fonctionné, merci beaucoup! – Masha

2

Vous faites select * dans une sous-requête. Vous devez retourner une seule colonne:

(SELECT * FROM dbo.func_Id1(@User)) 

à ceci:

(SELECT YOUR_USER_ID_COLUMN FROM dbo.func_Id1(@User)) 
+1

vous voulez dire, une seule colonne? – Masha

+0

oups, ouais mon mauvais. – kemiller2002

+0

la table de retour a une colonne, et je l'ai changé pour le nom, mais cela n'a pas aidé – Masha

1

Une déclaration de cas doit aboutir à une valeur, pas une expression. Donc cela ne fonctionnera pas:

select case when 1=1 then 1 in (1,2,3) end 

Mais cela fonctionnera;

select case when 1=1 then 1 end 

La valeur peut être le résultat d'une sous-requête. Donc, une solution serait de réécrire la clause where comme:

CASE @SomePRarmeter 
WHEN 'this' THEN 
    (SELECT count() FROM dbo.func_Id1(@User) f where f.user_id = t.user_id)) 
WHEN 'that' THEN 
    (SELECT count() from dbo.func_Ids2(@OrgsForReporter) f where f.user_id = t.user_id)) 
END > 1 

Maintenant, il retourne le nombre de lignes correspondant. Vous pouvez ensuite filtrer avec case ... end > 1.

0

Je brisaient ceci:

IF 'this' 
    SELECT 
    ... 
    WHERE user_id IN (SELECT * FROM dbo.func_Id1(@User)) 
ELSE IF 'that' 
    SELECT 
    ... 
    WHERE user_id IN (SELECT user_id from dbo.func_Ids2(@OrgsForReporter)) 
+0

La requête est énorme, je ne voudrais pas la réécrire simplement à cause de cette clause, mais je vous remercie pour votre suggestion. – Masha

0

CASE ... END retourne une expression, pas un morceau de code SQL littérale. Plutôt que:

AND CASE foo WHEN bar THEN bla=ble END -- Wrong 

... vous devez utiliser:

AND bla = CASE foo WHEN bar THEN ble END -- Right 

Dans votre cas, vous pouvez faire quelque chose sur cette ligne:

-- Untested 
AND (
    (@SomePRarmeter='this' AND user_id IN (SELECT * FROM dbo.func_Id1(@User))) 
    OR (@SomePRarmeter='that' AND user_id IN (SELECT user_id from bo.func_Ids2(@OrgsForReporter)) 
)