2010-11-05 53 views
1

Je travaille sur une procédure stockée et, à un moment donné, je veux vérifier ma variable de table pour voir s'il n'y a pas exactement zéro lignes avec un champ spécifique nul. En d'autres termes, pour chaque ligne de ma table, ce champ a une valeur non nulle. Je ne voudrais pas le faire en vérifiant count(), mais en utilisant EXISTS.SQL: vérifier si une table ne contient aucune valeur nulle dans une colonne particulière

Actuellement, je fais ceci:

IF EXISTS (SELECT * FROM @sometable where somefield IS NULL) 
     SET @somefield = @somefield /* just a way to skip this */ 
ELSE 
     /* perform some logic */ 

Maintenant, je sais que je peux utiliser PAS EXISTE, mais je suppose un pas EXISTE est beaucoup plus lent que EXISTS. Je jure que j'ai lu quelque chose récemment (sur SO je pense) qui avait un exemple de comment faire ce que je veux faire avec une clause Exists mais je ne peux pas le trouver et j'ai négligé de le mettre en signet. Bien que je me trompe peut-être. La raison pour laquelle je configure un if/else est que, d'après ce que j'ai compris, EXISTS retournera avant un NOT EXISTS et comme il s'agit d'une procédure stockée assez intensive (appelée assez fréquemment et parfois en masse), j'espère pouvoir en sauver traitement ici. Peut-être que je regarde tout faux ou suppose quelque chose de façon incorrecte. Je suis ici pour apprendre alors pointez-moi dans la bonne direction si j'ai tout faux.

Éditer: Apparemment il n'y a pas de différence dans ce contexte (ne faisant pas partie d'une clause where/sous-requête). Mais supposons que j'UTILISE existe dans une clause where et que je voulais vérifier le scénario exact ci-dessus (TOUTES les valeurs non nulles dans un champ) en particulier quand la table en question pourrait potentiellement avoir des milliers de lignes. [sorte de nouveau à SO, si je devrais le signaler comme sa propre question, s'il vous plaît faites le moi savoir]

+0

Un ** ** toutes les valeurs non nulles vérifient dans la clause where d'une requête principale est essentiellement le même contexte, puisqu'il ne sera exécuté qu'une seule fois par requête. Une vérification de toutes les valeurs non nulles dans une sous-requête est une très mauvaise idée, car elle nécessitera un balayage de table de la table concernée chaque fois que la sous-requête est exécutée. –

Répondre

3

Les deux EXISTS ou NOT EXISTS de ce format s'arrêteront lorsqu'ils trouveront une ligne et donneront vrai/faux selon le cas.

Le IF sautera en conséquence et il n'y a pas grand-chose à optimiser ici ...

+0

quand vous dites "ce format" faites-vous référence au fait que ce ne fait pas partie d'une clause where dans une requête? Si oui, (je sais que c'est une question totalement différente) quelle serait la différence là-bas? – pinkfloydx33

+0

Désolé, je ne fais pas partie d'une sous-requête. Ils peuvent donner des résultats différents dans certaines requêtes si vous avez IF EXISTS (SELECT WHERE EXISTS()) avec NOTs ici et là – gbn

0

NOT EXISTS et EXISTS devrait prendre le même temps. L'un ou l'autre peut être dérivé en calculant d'abord l'autre et en annulant le résultat.

+0

Dans son exemple, ne nous attendrions-nous pas à ce que 'NOT EXISTS' prenne plus de temps à cause de la logique sous-jacente (il cherchera un NOT NULL sur toutes les lignes au lieu d'un NULL sur une seule ligne). – JNK

+0

@JNK: Non - s'il n'y a pas de NULL sur un enregistrement, chaque version de la requête devra vérifier chaque enregistrement de la table, alors que s'il y a une valeur nulle, les deux requêtes seront exécutées jusqu'à ce que la première NULL soit trouvée. –

+1

@JNK: 'NOT EXISTS (SELECT * FROM @sometable O WH quelque chose N'EST PAS NUL)' teste que * chaque * ligne est nulle, ce qui n'est pas du tout la même chose. –