Question

J'ai lu des informations sur l'utilisation de l'expression CASE dans la clause WHERE ici:

http: // scottelkin. com / sql / utilisation-a-case-statement-in-a-sql-where-clause /

J'essaie de l'utiliser pour filtrer les résultats de mon instruction select, en fonction d'un numéro de contrat qui sera transmis par l'application de l'utilisateur. Mon code génère actuellement une erreur de 'Paramètre non valide', peu importe ce qui est passé. J'ai vérifié que SELECT / FROM fonctionnaient correctement, comme dans le cas d'une clause WHERE sans expression CASE. Voici mon code.

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END =
tblContracts.ContractNo)

La redondance du code est utilisée à des fins de dépannage. Je prévois d’utiliser le filtrage des caractères génériques sur CASE ultérieurement. Je me concentre sur l'obtention de la syntaxe pour le moment. Je pense que cela devrait renvoyer tous les enregistrements pour lesquels le paramètre correspond au numéro de contrat stocké dans la table. Toute aide ou conseil serait grandement apprécié.

Était-ce utile?

La solution

Après avoir lu votre explication, il existe un meilleur moyen de procéder sans CASE :

.
WHERE @ContractNo = 0 OR tblContracts.ContractNo = @ContractNo

Ceci renverra uniquement les numéros de contrat correspondants, à moins que @ContractNo ne vaut 0, auquel cas il renverra tous les enregistrements.

Modifier: je viens de remarquer que casperOne a proposé la même chose . Je n'ai pas vu ça. Grosse toi-même.

Autres conseils

Êtes-vous sûr de vouloir faire cela? Votre déclaration de cas retourne TOUJOURS @ContractNo . Je pense que ce que vous recherchez est la suivante:

where 
    case @ContractNo 
        when 0 then tblContracts.ContractNo 
        else @ContractNo 
    end = tblContracts.ContractNo

Le filtre ci-dessus indique "donnez-moi le contrat où le N ° de contrat est égal au paramètre, ou à la totalité si le paramètre est 0.

Le filtre précédent était uniquement filtré lorsque le champ du numéro de contrat était exactement égal au paramètre.

Quoi qu'il en soit, vous devriez le faire à la place:

where @ContractNo = 0 or @ContractNo = tblContracts.ContractNo

La logique est beaucoup plus facile à comprendre, et en plus (ne me citez pas dessus), l’optimiseur fonctionnera probablement mieux en dehors de la déclaration de cas.

Essayez de laisser de toute façon les parenthèses qui sont au mauvais endroit - la bonne devrait être après "END".

Peut-être avez-vous oublié de déclarer @ContractNo? Est-il comparable à 0 et à tblContracts.ContractNo?

Le message de Récursif a résolu mon problème avec précision.

J'ai vu des plaintes concernant la clarté de mon message original. Que puis-je faire à l'avenir pour que ce que je dis soit plus clair? Je ne suis pas habitué à poser des questions sur le code et à m'excuser pour tout ce qui a été confus. Dois-je simplement fournir les détails détaillés, comme dans mon deuxième message?

Merci encore pour votre aide.

Déplacez vos parenthèses proches avant le = comme suit:

WHERE     (CASE WHEN @ContractNo = 0 THEN @ContractNo ELSE @ContractNo END)=tblContracts.ContractNo

Je ne vois pas ce que cette instruction de cas va faire ... vous retournez la même chose dans le cas où @ContractNo = 0 ou si ce n'est pas ...

La syntaxe correcte est:

  Select...
  ...
  Where(
    Case
      When <Condition>
        Then <Return if true>
        Else <Return if false>
      End
 ) = <Whatever is being matched to the output of the case statement>

Toutefois, quelle que soit la syntaxe, votre exemple n'a pas beaucoup de sens. Si vous recherchez tous les éléments qui correspondent ou ont un numéro de contrat de 0, vous ferez alors:

Select...
...
Where (
  @ContractNo = 0 Or
  @ContractNo = tblContracts.ContractNo
)

Ce qui semble avoir beaucoup plus de sens que ce que vous essayez d’utiliser la déclaration case.

Modifier: Je dois avoir mal interprété légèrement la question. Le paramètre manquant signifie généralement que le paramètre (dans ce cas @ContractNo) n'est pas déclaré dans le champ de votre requête / procédure. Mais quelqu'un a déjà signalé cela, donc je ne peux en prendre aucun crédit.

La raison de la déclaration de casse, y compris l'ensemble "Si c'est 0, indiquez le paramètre, sinon, indiquez simplement le paramètre" était de le tester pour essayer d'obtenir la syntaxe correcte. À l’origine, j’avais essayé de dire "Si c’est 0, puis de passer"% "pour renvoyer chaque valeur. Le code que j'ai posté était dû au fait que je n'arrivais pas à obtenir le paramètre "Invalid Parameter" (Paramètre invalide) et pensais qu'il devait y avoir un problème avec ma syntaxe. Quand je l'ai séparé en correspondance de paramètre de base comme ça,

WHERE @ContractNo = tblContracts.ContractNo

il a bien rendu les enregistrements. Laissez-moi vous expliquer un peu plus.

Je sors d'un tas de tables différentes et filtre le contenu avec des informations non incluses dans l'instruction select (c'est-à-dire que tblContracts ne reçoit aucune information extraite de Select, elle n'est utilisée que dans Where). L'utilisateur sélectionnera dans une liste déroulante les différents numéros de contrat, ainsi que la valeur par défaut "Tous".

Je vais avoir un événement pour quand l'index de la liste déroulante change. Si c'est 'All', 0 sera passé en paramètre et je ne veux pas de filtrage. Sinon, je veux juste les informations pour ce numéro de contrat (la raison pour Else @ContractNo).

Vous ne voulez pas dire quelque chose comme ça?

SELECT * 
    FROM tblContracts
    WHERE     
    CASE 
       WHEN tblContracts.ContractNo = 0 THEN @ContractNo 
       ELSE tblContracts.ContractNo
    END = tblContracts.ContractNo

Où @ContractNo est une variable du même type de données que tblContracts.ContractNo

Pourquoi avez-vous même besoin d'une déclaration de cas?

WHen @ContractNo = 0 alors (0 = tblContracts.ContractNo) else @ContractNo then (@ContractNo = tblContracts.ContractNo)

Cela n’a aucun sens puisque vous pouvez simplement écrire ceci sous la forme

Où @contractNo = tblContracts.contractNo

Le numéro de contrat est-il réellement numérique ou s'agit-il toujours d'une chaîne de caractères numérique? Vérifiez vos types de données entre la table et le paramètre et l'instruction CASE (par exemple, "= 0" ou "= '0'")

Cette syntaxe devrait fonctionner (c'est le cas sous Oracle)

WHERE CASE WHEN tblContracts.ContractNo = 0 
           THEN @ContractNo 
           ELSE tblContracts.ContractNo
      END = tblContracts.ContractNo

quand vous dites:

  

Je sors d'un tas de tables différentes et filtre le contenu avec des informations non incluses dans l'instruction select (c'est-à-dire que tblContracts ne reçoit aucune information extraite de Select, elle n'est utilisée que dans Where). L'utilisateur sélectionnera dans une liste déroulante les différents numéros de contrat, ainsi que la valeur par défaut "Tous".

Il me semble alors que vous devriez avoir un " Où existe " clause. puisque vous ne tirez aucune information de cette table?!

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