Est-il nécessaire de tester NULL si également tester plus de?

J'ai hérité de vieilles procédures stockées aujourd'hui, et suis tombé sur plusieurs exemples qui ont suivi ce model général, où @Test est une valeur INT :

 IF @Test IS NOT NULL AND @Test > 0 -- do something... 

Ma compréhension est que si @Test est NULL , alors il n'a pas de valeur, et n'est pas supérieur à, inférieur ou égal à zéro. Par conséquent, tester NULL est redondant dans le code ci-dessus:

 IF @Test > 0 -- do something... 

Cette deuxième version semble fonctionner très bien, et est beaucoup plus lisible IHMO.

Donc, ma question: est-ce que ma compréhension de NULL est inutile dans ce cas précis, ou y a-t-il un cas d'utilisation évident que je néglige ici où tout pourrait mal tourner?

Note: Dans certains cas, il était évident que l'intention était de vérifier l'existence d'une valeur, et je les ai changés à IF EXISTS … Ma question concerne davantage le cas général décrit ci-dessus.

La comparaison avec NULL est nécessaire si vous utilisez des instructions ELSE:

par exemple:

 declare @t int set @t=null if (@t>0) print '1' -- works fine if (@t<0) print '2' --works fine if (@t>0) print '3' --works fine else print '4' --here we start getting problems, because we are sure that @t<=0 that is obviously not true 

En SQL, toutes les comparaisons avec une valeur NULL valent false. Vous devez donc toujours vérifier explicitement la valeur NULL si vous souhaitez agir en conséquence. Donc, dans ce cas, le test supplémentaire n'est pas nécessaire.

@ FlorianHeer est juste sur. NULL> 0 finira par évaluer false mais comme @Pred fait remarquer que c'est parce que Null> 0 évalue réellement à null et null cast à un bit est faux ….

Une nulle est une inconnue et par conséquent toute comparaison avec elle est également inconnue. Pensez aux fonctions arithmétiques telles que l'addition 1 + NULL = NULL , ou la concaténation 'A' + NULLL = NULL . NULL signifie que le moteur de database SQL ne peut pas interpréter sa valeur, donc toute fonction ou comparaison est également inconnue.

@MikkaRin a souligné que c'est l'hypothèse dans la partie ELSE d'une déclaration de cas ou d'une instruction IF où cela peut devenir problématique mais laisse également penser à cela dans le context d'une jointure et comment vous pouvez ou ne pas vouloir voir les résultats.

 DECLARE @Table1 AS TABLE (Col INT) DECLARE @Table2 AS TABLE (Col INT) INSERT INTO @Table1 VALUES (1),(2),(3) INSERT INTO @Table2 VALUES (1),(NULL),(3),(4) SELECT * FROM @Table1 t1 INNER JOIN @Table2 t2 ON t1.Col <> t2.Col 

Naturellement, vous pourriez penser que NULL ne serait pas égal à 1,2,3 qu'il devrait être inclus dans le jeu de résultats. Mais la valeur null est inconnue, donc SQL indique bien que je ne sais pas si NULL pourrait être 1,2,3, donc je ne peux pas returnner cela comme résultat.

Maintenant faisons la même chose mais ajoutons une valeur NULL dans la première table:

 DECLARE @Table1 AS TABLE (Col INT) DECLARE @Table2 AS TABLE (Col INT) INSERT INTO @Table1 VALUES (1),(2),(3),(NULL) INSERT INTO @Table2 VALUES (1),(NULL),(3),(4) SELECT * FROM @Table1 t1 INNER JOIN @Table2 t2 ON t1.Col = t2.Col 

Encore une fois, vous pourriez penser que NULL est = NULL mais toute comparaison de NULL est considérée comme inconnue, même si les deux tables ont la valeur NULL, elle ne sera pas returnnée dans l'set de données.

Maintenant considérez:

 DECLARE @Table1 AS TABLE (Col INT) INSERT INTO @Table1 VALUES (1),(2),(3),(NULL) SELECT *, CASE WHEN Col < 2 THEN Col ELSE 1000 END as ColCase FROM @Table1 t1 

Qui fera même le 1000 NULL la question est devrait NULL un inconnu être 1000? si NULL est inconnu, comment soaps-nous qu'il n'est pas inférieur à 2?

Pour un grand nombre de vos opérations, il suffit simplement de comparer @Value > 1 mais surtout lorsque vous commencez à traiter avec ELSE en cas d'instructions IF ou en rejoignant l'antithèse, vous devriez envisager de traiter les valeurs NULL. Telle que l'utilisation de ISNULL() ou COALESCE() comme le souligne @GuidoG.

IMHO étant explicite au sujet de vos intentions au cours des opérations pour tenir count adéquatement des valeurs nulles pèse les économies minimales de dactylographie.

vous pouvez le replace par

 if isnull(@test, 0) > 0 

De cette façon, il sera plus court et vous avez tout vérifié