2010-01-19 7 views
4

J'ai ce qui semble être une requête SQL vraiment facile que je ne peux pas comprendre et qui me rend fou. C'est SQL 2008. Fondamentalement, il y a un champ d'état où le peut choisir "en attente", "satisfait" ou tout. S'ils envoient "en attente" ou "satisfait", il n'y a pas de problème. Mais quand ils choisissent tous j'ai des problèmes. Principalement parce que je n'arrive pas à comprendre comment afficher les enregistrements où ce champ est nul (car il doit être 'est nul' au lieu de '= null'.) (C'est de cette façon que les données apparaîtront. n'a aucun contrôle sur cela.)En SQL, comment autoriser les valeurs nulles dans le paramètre?

Le code que je l'ai utilisé ne fonctionne pas pour les valeurs nulles.

SELECT * dE Payment_Table où Payment.Status_code = @status_id

+0

Je ne suis pas clair sur ce que vous essayez d'atteindre ici. Une valeur @status_id de NULL est-elle censée signifier "tous les statuts"? Ou est-ce censé correspondre à des lignes où Payment.Status_code est nul? –

+0

Sélectionnez * est une chose MAUVAISE à faire dans tous les cas. –

Répondre

5

Vous pouvez

SELECT Col1, Col2,...,Coln --Required Columns 
FROM Payment_Table 
where (Payment.Status_code = @status_id OR @status_id IS NULL) 
+1

Évitez select * (15 caractères) – JonH

+0

Je ne sais pas si cela va fonctionner. Il retournera toutes les lignes si @status_id est null au lieu de simplement les lignes où Payment.Status_code est null. –

+0

ne jamais faire Sélectionnez * –

0

Vous pouvez utiliser coa lesce ou IsNull sur votre champ Payment.StatusCode, cela vous permettra de faire une substitution pour null avec une valeur spécifique.

0
SELECT * 
FROM Payment_Table 
WHERE (Payment.Status_code is null or Payment.Status_code = @status_id) 
+0

Vous êtes conscient que cela inclura NULL Status_code même si un @status_id autre que NULL est fourni? –

+1

Je pense que l'affiche signifiait Payment.Status_Code = @status_id OU @Status_id EST NULL, sinon ce n'est pas correct. – JonH

+0

Oops, oui JonH, vous avez raison. –

1

Essayez

WHERE 
    ((@status_id IS NULL) OR (Payment.Status_code = @status_id)) 
2

Essayez:

SELECT * 
FROM Payment_Table 
WHERE Payment.Status_code = ISNULL(@status_id, Status_code) 

Cela renverra tous les paiements.

+2

Évitez SELECT * (15 caractères) – JonH

+0

S'il existe des lignes dans la table où Payment.Status_Code est null, votre requête ne retournera pas ces données. Ce code ne doit être utilisé que s'il y a une contrainte NOT NULL sur la colonne. –

-1

La meilleure façon de procéder est la suivante. Cependant, vous DEVEZ faire attention au reniflage des paramètres. Cela deviendra un problème car votre table s'agrandit et affectera vos temps d'exécution de façon aléatoire. C'est un problème ennuyeux qui peut apparaître. Utilisez le code ci-dessous.

CREATE PROCEDURE GetPaymentStatus 
@StatusID varchar(50)=NULL 
AS 
BEGIN 
SET NOCOUNT ON; 

DECLARE @StatusId_local varchar(50) 
SET @StatusID_local = @StatusId 

SELECT MyField1, MyField2 
FROM Payment_Table 
WHERE [email protected]_local 
    OR (@StatusID_local IS NULL AND Payment_Table.Status IS NULL) 
END 

Vérifiez ce paramètre sql article ou google renifler pour plus d'informations.

+0

Il est inutile de redéclarer cette variable. Aussi dans la plupart des cas ce n'est pas une application web/question de sécurité ... aussi cette procédure a déjà été posté par moi il y a 43 minutes. – JonH

+0

Il est utile de re-déclarer la variable. Je suis assez sûr qu'un problème de reniflage de paramètres pourrait survenir. J'ai vu cela se produire avant où une instruction ou est utilisée où la deuxième partie de la clause OR vérifie si une variable est définie sur NULL. C'est un bogue mineur dans SQL Server. Qu'est-ce qui se passe est SQL va scanner la table entière à la recherche de tous les cas où Payment_Table.Status = NULL, dont nous savons que ne donnera aucun résultat. Si vous déclarez la variable localement, vous forcez SQL à vérifier la partie de la clause OR qui n'implique pas la table. Voir mon lien ci-dessus. –

+0

Ce n'est pas vrai, parce que vous ne demandez pas payment_table.status = null vous demandez payment_table.status = @SomeVal où @SomeVal est en attente ou assigné, aucune mention de null de sorte que le moteur de db ne dérange pas faire toute recherche sur ça. – JonH

1
WHERE Payment_Table.Status = ISNULL(@StatusID, Payment_Table.Status) 

Il habituellement works better then OR

Edit: vous voulez sélectionner des lignes Payment_Table.Status = NULL lorsque @StatusID = NULL !!

SELECT * FROM Payment_Table where Payment.Status_code = @status_id 
UNION ALL 
SELECT * FROM Payment_Table where Payment.Status_code IS NULL AND @StatusID IS NULL 

OU

... 
WHERE 
    Payment_Table.Status @StatusID 
    OR 
    (Payment.Status_code IS NULL AND @StatusID IS NULL) 
Questions connexes