web-dev-qa-db-fra.com

Pourquoi NULL = NULL est-il évalué à false dans SQL Server?

Dans SQL Server, si vous avez nullParam=NULL dans une clause where, sa valeur est toujours false. C'est contre-intuitif et cela m'a causé beaucoup d'erreurs. Je comprends que les mots clés IS NULL et IS NOT NULL sont la bonne façon de le faire. Mais pourquoi le serveur SQL se comporte-t-il de cette façon?

120
Byron Whitlock

Pensez à null comme "inconnu" dans ce cas (ou "n'existe pas"). Dans les deux cas, vous ne pouvez pas dire qu'ils sont égaux, parce que vous ne connaissez pas la valeur de l'un ou l'autre. Ainsi, null = null est évalué comme non vrai (faux ou nul, selon votre système), car vous ne connaissez pas les valeurs pour dire qu'elles sont égales. Ce comportement est défini dans la norme ANSI SQL-92.

EDIT: Cela dépend de votre réglage ansi_nulls . Si ANSI_NULLS est désactivé, sa valeur sera évaluée à true. Exécutez le code suivant pour un exemple ...

set ansi_nulls off

if null = null
    print 'true'
else
    print 'false'


set ansi_nulls ON

if null = null
    print 'true'
else
    print 'false'
182
Scott Ivey

Quel âge a Frank? Je ne sais pas (null).

Quel âge a Shirley? Je ne sais pas (null).

Frank et Shirley ont-ils le même âge? 

La réponse correcte devrait être "je ne sais pas" (null), pas "non", car Frank et Shirley pourraient avoir le même âge, nous ne savons simplement pas. 

104
Neil McGuigan

J'espère ici clarifier ma position.

Ce NULL = NULL évaluer à FALSE est faux. Hacker et Mister ont répondu correctement NULL. Voici pourquoi. Dewayne Christensen m'a écrit, dans un commentaire à Scott Ivey :

Comme nous sommes en décembre, prenons un exemple saisonnier. J'ai deux cadeaux sous l'arbre. Maintenant, vous me dites si j'ai deux de la même chose ou pas.

Ils peuvent être différents ou égaux, vous ne savez pas tant que vous n'avez pas ouvert les deux cadeaux. Qui sait? Vous avez invité deux personnes qui ne se connaissent pas et toutes les deux vous ont fait le même cadeau - rare, mais pas impossible § .

Alors la question: ces deux inconnus présentent-ils le même (égal, =)? La réponse correcte est: UNKNOWN (c.-à-d. NULL).

Cet exemple était destiné à démontrer que ".. (false ou null, selon votre système) .." est une réponse correcte - ce n'est pas, seulement NULL est correct en 3VL (ou pouvez accepter un système qui donne de mauvaises réponses ?)

Une réponse correcte à cette question doit souligner ces deux points:

  • la logique à trois valeurs (3VL) est contre-intuitive (voir d'innombrables questions à ce sujet sur Stackoverflow et sur d'autres forums pour vous en assurer);
  • Les SGBD basés sur SQL ne respectent souvent même pas 3VL, ils donnent parfois des réponses erronées (comme l'affirme l'afficheur original, SQL Server le fait dans ce cas).

Donc, je répète: SQL ne force pas à interpréter la propriété réflexive d'égalité, qui stipule que:

for any x, x = x §§ (en anglais courant: quel que soit l'univers du discours, une "chose" est toujours égal à lui-même ).

.. dans un 3VL (TRUE, FALSE, NULL). Les attentes des personnes seraient conformes à 2VL (TRUE, FALSE, qui même en SQL est valable pour toutes les autres valeurs), c’est-à-dire x = x évalue toujours to TRUE, pour toute valeur possible de x - sans exception.

Notez également que les valeurs NULL sont des "non-valeurs" valides (comme leurs apologistes prétendent les être) que l’on peut affecter en tant que valeurs d’attribut (??) dans le cadre de variables relationnelles. Ce sont donc des valeurs acceptables de tous les types (domaine), pas seulement du type des expressions logiques.

Et c'était ce que je voulais : NULL, en tant que valeur, est une "bête étrange". Sans euphémisme, je préfère dire: un non-sens .

Je pense que cette formulation est beaucoup plus claire et moins discutable - désolée pour ma faible maîtrise de l’anglais.

Ceci est seulement un des problèmes de NULL. Mieux vaut les éviter complètement, lorsque cela est possible.

§ nous sommes préoccupés par les valeurs , donc le fait que les deux les cadeaux sont toujours deux objets physiques différents ne constituent pas une objection valable; si vous n'êtes pas convaincu, excusez-moi, ce n'est pas le lieu pour expliquer la différence entre la sémantique valeur et "objet" (Algèbre relationnelle a une sémantique de valeur depuis le début - voir le principe d'information de Codd; je pense que certains implémenteurs de SGBD SQL ne vous souciez même pas d’une sémantique commune).

§§ A ma connaissance, il s'agit d'un axiome accepté (sous une forme ou une autre, mais toujours interprété en 2VL) depuis l'Antiquité et que exactement car est tellement intuitif. 3VLs (une famille de logiques en réalité) est un développement beaucoup plus récent (mais je ne sais pas quand a été développé pour la première fois).

Note latérale: si quelqu'un introduira en bas , nité et option = Types comme tentatives pour justifier les valeurs NULL SQL, je ne serai convaincu qu'après un examen assez détaillé qui montrera comment les implémentations SQL avec les valeurs NULL ont un système de type sonore et clarifieront enfin ce que les valeurs NULL (ces "valeurs - pas valeurs ") sont vraiment.


Dans ce qui suit, je citerai quelques auteurs. Toute erreur ou omission appartient probablement à moi et non aux auteurs d'origine.

Joe Celko sur SQL NULL

Je vois Joe Celko souvent cité sur ce forum. Apparemment, il est un auteur très respecté ici. Alors, je me suis dit: "Qu'est-ce qu'il a écrit à propos de SQL NULL? Comment explique-t-il les nombreux problèmes de NULL?". Un de mes amis a une version ebook de SQL de Joe Celko pour smarties: programmation SQL avancée, 3e édition. Voyons voir.

Tout d'abord, la table des matières. Ce qui me frappe le plus, c’est le nombre de fois que NULL est mentionné et dans les contextes les plus variés:

3.4 Arithmétique et NULL 109
3.5 Conversion des valeurs en NULL 110
3.5.1 Fonction NULLIF () 110
6 NULL: données manquantes dans SQL 185
6.4 Comparaison des valeurs NULL 192
6.5 NULL et Logic 190
6.5.1 NULLS dans les prédicats de sous-requête 192
6.5.2 Solutions SQL standard 193
6.6 Maths et NULL 193
6.7 Fonctions et NULL 193
6.8 NULL et langues hôtes 194
6.9 Conseils de conception pour les valeurs NULL 195
6.9.1 Éviter les NULL des programmes hôtes 197
6.10 Note sur plusieurs valeurs NULL 198
10.1 IS NULL Prédicat 241
10.1.1 Sources des valeurs NULL 242
...

etc. Cela me dit "un cas spécial méchant".

J'aborderai certains de ces cas avec des extraits de ce livre, en essayant de me limiter à l'essentiel, pour des raisons de droit d'auteur. Je pense que ces citations relèvent du "fair use" doctrine et peuvent même inciter à acheter le livre - j'espère donc que personne ne se plaindra (sinon je devrai supprimer la plupart, sinon la totalité) . De plus, je m'abstiendrai de signaler des extraits de code pour la même raison. Désolé pour ça. Achetez le livre pour en savoir plus sur le raisonnement datailed.

Numéros de page entre parenthèses dans ce qui suit.

Contrainte NULL (11)

La contrainte de colonne la plus importante est NOT NULL, qui interdit l'utilisation de valeurs NULL dans une colonne. Utilisez cette contrainte régulièrement et ne la supprimez que lorsque vous avez de bonnes raisons. Cela vous aidera à éviter les complications de valeurs NULL lorsque vous effectuez des requêtes sur les données.

Ce n'est pas une valeur ; c'est un marqueur qui tient une place où une valeur peut aller.

Encore une fois cette absurdité "valeur mais pas tout à fait une valeur". Le reste me semble assez raisonnable.

(12)

En bref, les valeurs NULL entraînent de nombreuses fonctionnalités irrégulières dans SQL, dont nous parlerons plus loin. Votre meilleur pari est simplement de mémoriser les situations et les règles pour les valeurs NULL lorsque vous ne pouvez pas les éviter.

À propos de SQL, NULL et infini:

(104) CHAPITRE 3: DONNÉES NUMÉRIQUES EN SQL

SQL n'a pas accepté le modèle IEEE pour les mathématiques pour plusieurs raisons.

...

Si les règles IEEE pour les mathématiques étaient autorisées dans SQL, nous aurions besoin de règles de conversion de type pour l'infini et d'un moyen de représenter une valeur numérique exacte infinie après la conversion. Les gens ont assez de problèmes avec les valeurs NULL, alors n’y allons pas.

Les implémentations SQL indécises sur ce que NULL signifie réellement dans des contextes particuliers:

3.6.2 Fonctions exponentielles (116)

Le problème est que les logarithmes ne sont pas définis quand (x <= 0). Certaines implémentations SQL renvoient un message d'erreur, d'autres renvoient un NULL et DB2/400; la version 3 version 1 renvoyait * NEGINF (abréviation de "infini négatif") comme résultat.

Joe Celko citant David McGoveran et C. J. Date:

6 NULL: données manquantes dans SQL (185)

Dans leur livre Guide de Sybase et de SQL Server, David McGoveran et CJ Date ont déclaré: "C’est l’opinion de ce rédacteur. valent et devraient être évités; ils affichent un comportement très étrange et incohérent et peuvent constituer une source riche d'erreurs et de confusion. (Veuillez noter que ces commentaires et critiques s’appliquent à tout système prenant en charge les valeurs NULL de style SQL, et pas seulement à SQL Server en particulier.) "

NULL en tant que toxicomanie:

(186/187)

Dans la suite de ce livre, , je vous exhorterai à ne pas les utiliser , ce qui peut paraître contradictoire, mais ce n'est pas le cas. Pensez à une valeur nulle comme une drogue; utilisez-le correctement et cela fonctionne pour vous, mais en abusez et cela peut tout gâcher. Votre meilleure politique consiste à éviter les NULL lorsque vous le pouvez et à les utiliser correctement lorsque vous devez.

Mon objection unique ici est de "les utiliser correctement", ce qui interagit mal avec des comportements de mise en œuvre spécifiques.

6.5.1 NULLS dans les prédicats de sous-requête (191/192)

Les gens oublient qu'une sous-requête cache souvent une comparaison avec une valeur NULL. Considérez ces deux tables:

...

Le résultat sera vide. C'est contre-intuitif , mais correct.

(séparateur)

6.5.2 Solutions SQL standard (193)

SQL-92 a résolu certains problèmes de la logique 3VL (logique à trois valeurs) en ajoutant un nouveau prédicat de la forme:

<condition de recherche> IS [PAS] VRAI | FAUX | INCONNU

Mais UNKNOWN est une source de problèmes en soi, si bien que C. J. Date, dans son livre cité ci-dessous, est recommandé dans le chapitre 4.5. Eviter les nulls dans SQL:

  • N'utilisez pas le mot clé UNKNOWN dans quelque contexte que ce soit.

Lire "ASIDE" sur UNKNOWN, également lié ci-dessous.

6.8 NULL et langues hôtes (194)

Cependant, vous devez savoir comment les valeurs NULL sont gérées lorsqu'elles doivent être transmises à un programme hôte. Aucun langage hôte standard pour lequel une incorporation est définie ne prend en charge les valeurs NULL, ce qui constitue une autre bonne raison d'éviter de les utiliser dans votre schéma de base de données.

(séparateur)

6.9 Conseils de conception pour les valeurs NULL (195)

C'est une bonne idée de déclarer toutes vos tables de base avec des contraintes NOT NULL sur toutes les colonnes autant que possible. Les valeurs NULL confondent les utilisateurs qui ne connaissent pas le code SQL et les valeurs NULL sont coûteuses.

Objection: Les valeurs NULL confondent même les personnes qui connaissent bien le langage SQL, voir ci-dessous.

(195)

Les valeurs NULL doivent être évitées dans les clés étrangères. SQL permet cette relation "bénéfice du doute", mais peut entraîner une perte d'informations dans les requêtes impliquant des jointures. Par exemple, si un code de numéro de pièce dans Inventory est référencé comme FOREIGN KEY par une table Orders, vous aurez des difficultés à obtenir une liste des pièces ayant un NULL. C'est une relation obligatoire. vous ne pouvez pas commander une pièce qui n'existe pas.

(séparateur)

6.9.1 Éviter les NULL des programmes hôtes (197)

Vous pouvez éviter de mettre des valeurs NULL dans la base de données à partir des programmes hôtes avec une certaine discipline de programmation.

...

  1. Déterminez l'impact des données manquantes sur la programmation et la génération de rapports: Les colonnes numériques avec des valeurs NULL posent un problème, car les requêtes utilisant des fonctions d'agrégation peuvent donner des résultats trompeurs.

(séparateur)

(227)

La somme () d'un ensemble vide est toujours NULL. L'une des erreurs de programmation les plus courantes commises lors de l'utilisation de cette astuce consiste à écrire une requête pouvant renvoyer plusieurs lignes. Si vous n'y avez pas pensé, vous avez peut-être écrit le dernier exemple sous la forme: ...

(séparateur)

10.1.1 Sources des valeurs NULL (242)

Il est important de se rappeler où les valeurs NULL peuvent se produire. Ils sont plus qu'une simple valeur possible dans une colonne . Les fonctions d'agrégation sur des ensembles vides, des jointures externes, des expressions arithmétiques avec des valeurs NULL et des opérateurs OLAP renvoient toutes des valeurs NULL. Ces constructions apparaissent souvent sous forme de colonnes dans VIEW.

(séparateur)

(301)

Un autre problème lié aux valeurs NULL est rencontré lorsque vous essayez de convertir des prédicats IN en prédicats EXISTS.

(séparateur)

16.3 Fonctions ALL pour les prédicats et les extrema (313)

Au début, il est contre-intuitif que ces deux prédicats ne soient pas les mêmes en SQL:

...

Mais vous devez vous rappeler les règles pour les fonctions extrema: elles suppriment toutes les valeurs NULL avant de renvoyer les valeurs supérieures ou inférieures. Le prédicat ALL ne supprime pas les valeurs NULL, vous pouvez donc les inclure dans les résultats.

(séparateur)

(315)

Cependant, la définition dans la norme est libellée en négatif, de sorte que les valeurs NULL bénéficient du doute. ...

Comme vous pouvez le constater, il vaut mieux éviter les valeurs NULL dans les contraintes UNIQUE.

Discuter de GROUP BY:

Les valeurs NULL sont traitées comme si elles étaient toutes égales entre elles et forment leur propre groupe. Chaque groupe est ensuite réduit à une seule ligne dans une nouvelle table de résultats qui remplace l'ancienne.

Cela signifie que pour GROUP BY, la clause NULL = NULL n'est pas évaluée à NULL, comme dans 3VL, mais à TRUE.

Le standard SQL est déroutant:

Les ORDER BY et NULL (329)

Si une valeur de clé de tri NULL est considérée supérieure ou inférieure à une valeur non NULL, elle est définie par l'implémentation, mais ...

... Il existe des produits SQL qui le font de toute façon.

En mars 1999, Chris Farrar a soulevé une question de l’un de ses développeurs qui l’a amené à examiner une partie du standard SQL que je pensais avoir comprise . Chris a trouvé quelques différences entre la compréhension générale et le libellé actuel de la spécification .

Etc. Je pense est suffisant par Celko.

C. J. Date sur les valeurs NULL SQL

La date du C. J. est plus radicale à propos des NULL: évitez les NULL en SQL, point. En fait, le chapitre 4 de son SQL et théorie relationnelle: comment écrire un code SQL précis s'intitule "NO DUPLICATES, NO NULLS", avec des sous-chapitres "4.4 Qu'est-ce qui ne va pas avec Nulls?" et "4.5 Eviter les Nulls en SQL" (suivez le lien: grâce à Google Livres, vous pouvez lire certaines pages en ligne).

Fabian Pascal sur SQL NULL

De ses Problèmes pratiques dans la gestion de base de données - Une référence pour le praticien qui réfléchit ​​(pas d'extraits en ligne, désolé):

10.3 Implications pratiques

10.3.1 NULL SQL

... SQL souffre des problèmes inhérents à 3VL ainsi que de nombreuses bizarreries, complications, contre-intuitions et erreurs absolues [10, 11]; parmi eux sont les suivants:

  • Les fonctions d'agrégation (par exemple, SUM (), AVG ()) ignorent les valeurs NULL (à l'exception de COUNT ()).
  • Une expression scalaire sur une table sans lignes est évaluée incorrectement à NULL au lieu de 0.
  • L'expression "NULL = NULL" est évaluée à NULL, mais n'est pas valide en SQL; pourtant ORDER BY considère les NULL comme égaux (tout ce qui précède ou suit des valeurs "normales" est laissé au fournisseur de SGBD).
  • L'expression "x IS NOT NULL" n'est pas égale à "NOT (x IS NULL)", comme c'est le cas dans 2VL.

...

Tous les dialectes SQL implémentés dans le commerce suivent cette approche 3VL. Ainsi, non seulement ils exposent ces problèmes, mais ils ont également des problèmes d’implémentation spécifiques, qui varient selon les produits .

26
MaD70

Cela dépend peut-être, mais je pensais que NULL=NULL est évalué à NULL comme la plupart des opérations avec NULL comme opérande.

Ce n'est pas parce que vous ne savez pas ce que sont les deux choses qu'elles sont égales. Si vous pensez à NULL si vous pensez à «NULL» (chaîne), vous voudrez probablement un test d'égalité différent, comme IS DISTINCT FROM AND IS NOT DISTINCT FROM

http://www.postgresql.org/docs/8.4/static/functions-comparison.html

expression IS DISTINCT FROM expression

expression IS PAS DISTINCT FROM expression

Pour les entrées non nulles, IS DISTINCT FROM est identique à l'opérateur <>. Cependant, si les deux entrées sont nulles, cela retourne false et si une seule entrée est nulle, elle retourne vrai. De même, IS NOT DISTINCT FROM est identique à = pour les entrées non nulles, mais renvoie true lorsque les deux entrées sont nulles et false lorsqu'une seule entrée est vide. Ainsi, ces constructions agissent effectivement comme si null était une valeur de données normale, plutôt que "inconnu".

5
Evan Carroll

NULL n'est égal à rien, pas même à lui-même. Ma solution personnelle pour comprendre le comportement de NULL est d'éviter de l'utiliser autant que possible :).

4
Chris R. Timmons

Sur technet , il existe une bonne explication sur le fonctionnement des valeurs nulles.

Null signifie inconnu. 

Par conséquent l'expression booléenne 

valeur = null 

n'évalue pas à false, mais null, mais s'il s'agit du résultat final d'une clause where, rien n'est renvoyé. C'est une façon pratique de le faire, car renvoyer null serait difficile à concevoir.

Il est intéressant et (très important} de comprendre ce qui suit: 

Si dans une requête nous avons 

where (value=@param Or @param is null) And id=@anotherParam

et 

  • valeur = 1 
  • @param est null 
  • id = 123 
  • @ anotherParam = 123

puis 

"value = @ param" est évalué à null
"@ param is null" est évalué à true
"id = @ anotherParam" est évalué à true 

Donc, l'expression à évaluer devient 

(nul ou vrai) et vrai 

Nous pourrions être tentés de penser qu'ici, "null Or true" sera évalué comme "null". Ainsi, l'expression entière devient null et la ligne ne sera pas renvoyée. 

Ce n'est pas le cas. Pourquoi? 

Parce que "null Or true" est évalué à true, ce qui est très logique, car si un opérande est true avec l'opérateur Or, alors, quelle que soit la valeur de l'autre opérande, l'opération renvoie true. Ainsi, peu importe que l'autre opérande soit inconnu (null). 

Donc nous avons finalement true = true et ainsi la ligne sera retournée.

Remarque: avec la même logique claire que "null Or true" évaluée à true, "null And true" évaluée à null.

Mettre à jour:
Ok, pour terminer, je veux ajouter le reste ici aussi, ce qui s'avère assez amusant par rapport à ce qui précède. 

"null Or false" est évalué à null, "null And false" est évalué à false. :)

La logique est toujours aussi évidente qu’avant.

4
Magnus

Le concept de NULL est discutable, pour le moins. Codd a introduit le modèle relationnel et le concept de NULL dans son contexte (et a proposé plus d'un type de NULL!) Cependant, la théorie relationnelle a évolué depuis les écrits originaux de Codd: certaines de ses propositions ont depuis été abandonnées (par exemple, clé primaire). et d’autres n’ont jamais été capturés (par exemple, les opérateurs thêta). Dans la théorie relationnelle moderne (la théorie véritablement relationnelle, je devrais souligner), NULL n'existe tout simplement pas. Voir le troisième manifeste. http://www.thethirdmanifesto.com/

Le langage SQL souffre du problème de la compatibilité ascendante. NULL a trouvé sa place dans SQL et nous sommes coincés avec. On peut soutenir que l'implémentation de NULL dans SQL est défectueuse (l'implémentation de SQL Server rend les choses encore plus compliquées en raison de son option ANSI_NULLS). 

Je recommande d'éviter l'utilisation de colonnes NULLable dans les tables de base.


Bien que peut-être je ne devrais pas être tenté, je voulais juste affirmer une de mes propres corrections sur la façon dont NULL fonctionne en SQL:

NULL = NULL est évalué à UNKNOWN.

UNKNOWN est une valeur logique. 

NULL est une valeur de donnée.

C'est facile à prouver, par exemple. 

SELECT NULL = NULL 

génère correctement une erreur dans SQL Server. Si le résultat était une valeur de données, nous nous attendrions à voir NULL, comme certaines réponses (à tort) suggèrent que nous le ferions.

La valeur logique UNKNOWN est traitée différemment dans SQL DML et SQL DDL, respectivement.

Dans SQL DML, UNKNOWN entraîne la suppression des lignes du jeu de résultats. 

Par exemple:

CREATE TABLE MyTable
(
 key_col INTEGER NOT NULL UNIQUE, 
 data_col INTEGER
 CHECK (data_col = 55)
);

INSERT INTO MyTable (key_col, data_col)
   VALUES (1, NULL);

La INSERT réussit pour cette ligne, même si la condition CHECK est résolue en NULL = NULL. Ceci est dû à la norme SQL-92 ("ANSI"):

11.6 définition de contrainte de table

3)

Si la contrainte de la table est une vérification définition de contrainte, puis laisser SC être la condition de recherche immédiatement contenues dans la contrainte de vérification définition et soit T le nom de la table inclus dans le tableau correspondant descripteur de contrainte; la table la contrainte n'est pas satisfaite si et seulement si

EXISTS (SÉLECTIONNEZ * DE T WHERE NOT (SC))

est vrai.

Lisez cela à nouveau attentivement, en suivant la logique.

En clair, notre nouvelle ligne ci-dessus bénéficie du "bénéfice du doute" sur UNKNOWN et est autorisée à passer.

Dans SQL DML, la règle pour la clause WHERE est beaucoup plus facile à suivre:

La condition de recherche est appliquée à chaque ligne de T. Le résultat de où clause est un tableau de ces lignes de T pour lequel le résultat de la recherche la condition est vraie.

En clair, les lignes dont la valeur est UNKNOWN sont supprimées du jeu de résultats.

4
onedaywhen

La confusion provient du niveau d'indirection (abstraction) résultant de l'utilisation de NULL

Pour revenir à l'analogie "qu'il y a sous l'arbre de Noël", "Inconnu" décrit l'état des connaissances sur le contenu de la case A. 

Donc, si vous ne savez pas ce qu'il y a dans la case A, vous dites que c'est "inconnu", mais cela ne veut pas dire que "inconnu" est à l'intérieur de la case. Quelque chose d'autre qu'inconnu se trouve dans la boîte, éventuellement un objet ou rien dans la boîte. 

De même, si vous ne savez pas ce qu'il y a dans la case B, vous pouvez étiqueter votre état des connaissances sur le contenu comme étant "inconnu". 

Alors, voici le kicker: Votre état des connaissances sur la case A est égal à votre état des connaissances sur la case B . (Dans les deux cas, votre état des connaissances est "Inconnu" ou "Je ne sais pas ce qu'il y a dans la boîte".) Mais le contenu des boîtes peut être différent ou non. 

Pour revenir à SQL, vous ne devriez idéalement pouvoir comparer les valeurs que si vous les connaissez. Malheureusement, l'étiquette qui décrit un manque de connaissances est stockée dans la cellule elle-même , nous sommes donc tentés de l'utiliser comme valeur. Mais nous ne devrions pas utiliser cela comme une valeur, car cela conduirait à ce que "le contenu de la case A soit égal à celui de la case B lorsque nous ne savons pas ce qui est dans la case A et/ou nous ne savons pas ce qui est dans la case B. (Logiquement, l'implication "si je ne sais pas ce qu'il y a dans la case A et si je ne sais pas ce qu'il y a dans la case B, le contenu de la case A = ce qui se trouve dans la case B" est fausse.)

Yay, cheval mort.

3
TomEberhard

MSDN a un article descriptif de Nice sur les valeurs NULL et la logique à trois états qu’elles engendrent.

En bref, la spécification SQL92 définit NULL comme inconnu et NUL utilisé dans les opérateurs suivants provoque des résultats inattendus pour les non-initiés:

= operator NULL   true   false 
NULL       NULL   NULL   NULL
true       NULL   true   false
false      NULL   false  true

and op     NULL   true   false 
NULL       NULL   NULL   false
true       NULL   true   false
false      false  false  false

or op      NULL   true   false 
NULL       NULL   true   NULL
true       true   true   true
false      NULL   true   false
3
Paul Wagland

Parce que NULL signifie 'valeur inconnue' et que deux valeurs inconnues ne peuvent pas être égales.

Donc, si notre logique NULLn ° 1 est égale à NULLn ° 2, alors nous devons dire que

SELECT 1
WHERE ISNULL(nullParam1, -1) = ISNULL(nullParam2, -1)

où la valeur connue -1 N ° 1 est égale à -1 N ° 2

3
armen

La question:
Un inconnu est-il égal à un autre inconnu?
(NULL = NULL)
Cette question est quelque chose que personne ne peut répondre, elle est donc par défaut vraie ou fausse selon votre réglage ansi_nulls.

Cependant la question:
Cette variable inconnue est-elle inconnue?
Cette question est très différente et peut être répondue avec true.

nullVariable = null compare les valeurs
nullVariable est null compare l'état de la variable

2
user224385

Juste un ajout à d’autres merveilleuses réponses:

AND: The result of true and unknown is unknown, false and unknown is false,
while unknown and unknown is unknown.

OR: The result of true or unknown is true, false or unknown is unknown, while unknown or unknown is unknown.

NOT: The result of not unknown is unknown
0
Kiren Siva

Si vous recherchez une expression retournant true pour deux NULL, vous pouvez utiliser:

SELECT 1 
WHERE EXISTS (
    SELECT NULL
    INTERSECT
    SELECT NULL
)

Il est utile si vous souhaitez répliquer des données d'une table à une autre.

0
Piotr

null est inconnu en sql, nous ne pouvons donc pas nous attendre à ce que deux inconnus soient identiques.

Cependant, vous pouvez obtenir ce comportement en définissant ANSI_NULLS sur Off (sa valeur par défaut) Vous pourrez utiliser l'opérateur = pour les valeurs NULL.

SET ANSI_NULLS off
if null=null
print 1
else 
print 2
set ansi_nulls on
if null=null
print 1
else 
print 2
0
ps.

Les réponses ici semblent toutes venir du point de vue du CS, je souhaite donc en ajouter une du point de vue du développeur.

Pour un développeur, NULL est très utile. Les réponses ici disent que NULL signifie inconnu, et peut-être que dans la théorie CS, c'est vrai, ne vous en souvenez pas, cela fait longtemps. Dans le développement actuel, au moins selon mon expérience, cela se produit environ 1% du temps. Les 99% restants sont utilisés dans les cas où la valeur n'est pas UNKNOWN mais est connue pour être absente.

Par exemple:

  • Client.LastPurchase, pour un nouveau client. Ce n'est pas inconnu, on sait qu'il n'a pas encore acheté.

  • Lors de l'utilisation d'un ORM avec un mappage Table par ClasseHiérarchie , certaines valeurs ne sont tout simplement pas mappées pour certaines classes.

  • Lorsque vous mappez un arborescence }, une racine aura généralement Parent = NULL

  • Et beaucoup plus...

Je suis sûr que la plupart des développeurs ont à un moment donné écrit WHERE value = NULL, N'ayant obtenu aucun résultat, et c'est ainsi qu'ils ont appris la syntaxe IS NULL. Il suffit de regarder combien de votes cette question et ceux liés ont.

Les bases de données SQL sont un outil, et elles doivent être conçues de la manière la plus facile à comprendre pour les utilisateurs.

0
AlexDev