Problèmes avec SQL et de comparaison des valeurs null
J'ai une requête qui met à jour un champ dans une table lorsque la valeur ne correspond pas à un champ d'une autre table.
UPDATE table1
SET a.field1 = b.field3
FROM table1 a ,
table2 b
WHERE a.field2 = b.field2
AND a.field1 <> b.field3
Le problème que j'ai c'est que c'est de ne pas décrocher quand un.champ1 est nulle et b.field3 est une valeur OU si un.champ1 est une valeur et b.field3 est null.
J'ai contourné ce problème en ajoutant ce qui suit...
UPDATE table1
SET a.field1 = b.field3
FROM table1 a ,
table2 b
WHERE a.field2 = b.field2
AND ( a.field1 <> b.field3
OR (a.field1 IS NOT NULL
AND b.field3 IS NULL)
OR (a.field1 IS NULL
AND b.field3 IS NOT NULL)
)
Ma question est plus centrée autour de pourquoi ce qui se passe et quelle est la meilleure structure de la requête dans le but d'éviter cela?
Null est égal à rien, c'est une valeur non définie qui vous ne peut pas le comparer à quoi que ce soit(même si vous utilisez
double possible de Pas égal à <> != opérateur en T-SQL sur NULL
J'ai couru dans la "face" problème récemment. Quelqu'un a fourni une instruction SQL pour moi involing comparaison
<>
). C'est pourquoi la valeur null dossiers sont omis. Par conséquent, vous devez utiliser IS NULL
ou IS NOT NULL
explicitement.double possible de Pas égal à <> != opérateur en T-SQL sur NULL
J'ai couru dans la "face" problème récemment. Quelqu'un a fourni une instruction SQL pour moi involing comparaison
WHERE val=null ...
et fait sur notre sql-server également à WHERE val IS NULL
! Il s'est avéré, il y a un paramètre SET ANSI_NULLS OFF
qui a été activé sur notre serveur. Ce (obsolète!!) réglage permet de nulle comparaisons, voir ici.OriginalL'auteur Heather | 2013-04-10
Vous devez vous connecter pour publier un commentaire.
Le problème est NULLE comparaison. Si un.champ1 ou b.field3 est NULL, vous devez utiliser un is NULL ou is not NULL déclaration. Vous pouvez utiliser une valeur par défaut pour un.champ1 et b.field3 avec la fonction ISNULL.
dans ce cas, il s'agit d'une comparaison avec la valeur 0.
"Si elle [semble] pour le travail", alors il n'a pas les moyens est une "[bon] solution". Et si
a.field1 = 0 AND b.field3 IS NULL
?0 DOIT être arbitraire et hors de la portée de la valeur. Le but est de garder à l'aide de la <> de l'opérateur. Il pourrait être -1, etc ...
Si, pour une ligne, la valeur de champ1 est NULLE et la valeur de field3 est 0 alors le résultat de
ISNULL(a.field1,0) <> ISNULL(b.field3,0)
est "faux". Mais le résultat dea.field1 IS NULL AND b.field3 IS NOT NULL
sera "vrai".Je suis d'accord avec Norberto ici. ISNULL est juste une fonction, vous pouvez l'utiliser n'importe où vous voulez à condition que vous comprenez les risques et les mises en garde de l'utilisation de fonctions. J'utilise souvent cette tendance rapide à la volée requêtes afin d'éviter toute forme de spaghettis requête semblable à celui de l'op est venu avec comme solution.
OriginalL'auteur Norberto108
Le résultat de la comparaison de quelque chose de NUL, même de lui-même, est toujours NULLE(pas de VRAI ou FAUX).
Utiliser l'option EXISTE, et à l'EXCEPTION des opérateurs.
ISNULL()
option fonctionne très bien, jusqu'à ce qu'il n'a pas.OriginalL'auteur Aleksandr Fedorenko
En plus de gérer la valeur NULL logique correctement, vous devez joindre plusieurs conditions qui doivent être appliquées conjointement entre parenthèses.
Quelque chose comme ça (pas sûr que j'ai compris de vos conditions exactement).
OriginalL'auteur DOK
Tim Shmelter est droit dans son commentaire,
NULL
n'est pas égal à quoi que ce soit - même, y comprisNULL
.NULL
littéralement signifie que la valeur est inconnue.Ce qui signifie que même si
a.field1
etb.field3
les deux sontNULL
, les conditionsa.field1 <> b.field3
ainsi quea.field1 = b.field3
les deux renverra toujours false. Essayez et vous verrez!Je pense que la solution ne réside pas dans le
IFNULL
fonction de SQL Server. Il se trouve plus dans votre adhésion à la logique. Vous avez déjà votre solution, c'est à dire, la deuxième requête dans votre question. Ce que je recommande est de vous jouer un peu plus avecNULL
valeurs de sorte que vous pouvez comprendre ce que sont vraiment ils.Petite correction: si l'une (ou les deux).champ1 ou b.field3 sont NULLES, les conditions d'un.champ1 <> b.field3 et un.champ1 = b.field3 ne reviendra pas FAUX, mais plutôt la valeur NULL. Il va se comporter comme FAUX dans la plupart des cas (comme celui-ci), car il n'est pas VRAI, mais c'est encore un FAUX pas et c'est à dire ne peut pas être niée retour à la VRAIE. Si vous ne mettez PAS en avant (un.champ1 = b.champ3) il sera toujours NULL et se comportent comme des FAUX.
Cela a été très utile commentaire. On dirait que vous avez joué avec beaucoup de zéros!
OriginalL'auteur Rachcha
Vous pouvez utiliser fusionnent dans sql server par défaut la valeur d'une colonne à une valeur non nulle. Fusionner renvoie la première valeur non nulle dans la liste.
J'ai supposé que votre type de numéro, mais vous pouvez utiliser d'autres types de données. J'ai aussi supposé que si les deux valeurs sont NULLES alors les deux lignes sont équivalentes.
OriginalL'auteur Chanoch
Lorsque vous écrivez dans votre requête
a.field1 = b.field3
vous avez réellement faire deux hypothèses: champ1 table doit contenir une valeur et champ3 dans votre b tableau doit également contenir une valeur. Il n'est pas possible de comparer un " manque d'information et inapplicable à une valeur. Le résultat de cette comparaison est inconnue. Vous pouvez jeter un œil pour plus d'informations sur Wikipedia.OriginalL'auteur KookieMonster
Il s'agira de vérifier si la Colonne1 et Colonne2 est égal, en Outre utilisé la Conversion de type VARBINARY à comparer à la casse et que vous pouvez le supprimer si pas nécessaire.
Vous pouvez changer la fin de l'expression de
IS NOT NULL
pour la vérification de l'inégalité de condition.Espérons que cette aide.
OriginalL'auteur QMaster
Un autre moyen serait d'utiliser Somme de contrôle fonction
OriginalL'auteur Captain O.