Je sais qu'il ne considère « » comme NULL
, mais qui ne fait pas grand - chose à me dire pourquoi cela est le cas. Si je comprends bien les spécifications SQL, '' n'est pas la même chose que NULL
- l'une est une donnée valide et l'autre indique l'absence de cette même information.
N'hésitez pas à spéculer, mais veuillez indiquer si c'est le cas. S'il y a quelqu'un d'Oracle qui peut le commenter, ce serait fantastique!
Réponses:
Je crois que la réponse est qu'Oracle est très, très vieux.
Dans le passé, avant qu'il n'y ait un standard SQL, Oracle a décidé que les chaînes vides dans
VARCHAR
/VARCHAR2
colonnes étaientNULL
et qu'il n'y avait qu'un sens de NULL (il existe des théoriciens relationnels qui feraient la différence entre des données qui n'ont jamais été demandées, données où la réponse existe mais n'est pas connue de l'utilisateur, données où il n'y a pas de réponse, etc. qui constituent toutes un sensNULL
).Au moment où la norme SQL est apparue et a convenu que
NULL
la chaîne vide était des entités distinctes, il y avait déjà des utilisateurs Oracle qui disposaient d'un code supposant que les deux étaient équivalents. Il restait donc essentiellement à Oracle la possibilité de casser le code existant, de violer la norme SQL ou d'introduire une sorte de paramètre d'initialisation qui changerait la fonctionnalité d'un nombre potentiellement important de requêtes. La violation du standard SQL (IMHO) était la moins perturbatrice de ces trois options.Oracle a laissé ouverte la possibilité que le
VARCHAR
type de données change dans une future version pour adhérer à la norme SQL (c'est pourquoi tout le monde utiliseVARCHAR2
dans Oracle puisque le comportement de ce type de données est garanti de rester le même à l'avenir).la source
Tom Kyte VP d'Oracle:
la source
''
est en cours implicitement converti en un VARCHAR2, par exemple ,cast('' as char(1)) is null
qui est ... étonnamment TRUEJe soupçonne que cela a beaucoup plus de sens si vous pensez à Oracle comme les développeurs précédents l'ont probablement fait - en tant que backend glorifié pour un système de saisie de données. Chaque champ de la base de données correspond à un champ sous une forme qu'un opérateur de saisie de données a vu sur son écran. Si l'opérateur n'a rien saisi dans un champ, que ce soit "date de naissance" ou "adresse", les données de ce champ sont "inconnues". Il n'y a aucun moyen pour un opérateur d'indiquer que l'adresse de quelqu'un est vraiment une chaîne vide, et cela n'a pas vraiment de sens de toute façon.
la source
La documentation Oracle alerte les développeurs de ce problème, remontant au moins jusqu'à la version 7.
Oracle a choisi de représenter NULLS par la technique de la «valeur impossible». Par exemple, un NULL dans un emplacement numérique sera stocké comme "moins zéro", une valeur impossible. Tous les zéros négatifs résultant des calculs seront convertis en zéro positif avant d'être stockés.
Oracle a également choisi, à tort, de considérer la chaîne VARCHAR de longueur zéro (la chaîne vide) comme une valeur impossible et un choix approprié pour représenter NULL. Il s'avère que la chaîne vide est loin d'être une valeur impossible. C'est même l'identité sous l'opération de concaténation de chaînes!
La documentation Oracle avertit les concepteurs et les développeurs de bases de données qu'une future version d'Oracle pourrait rompre cette association entre la chaîne vide et NULL, et rompre tout code qui dépend de cette association.
Il existe des techniques pour signaler des valeurs NULL autres que des valeurs impossibles, mais Oracle ne les a pas utilisées.
(J'utilise le mot "emplacement" ci-dessus pour désigner l'intersection d'une ligne et d'une colonne.)
la source
La chaîne vide est identique à NULL simplement parce que c'est le "moindre mal" par rapport à la situation où les deux (chaîne vide et null) ne sont pas identiques.
Dans les langues où NULL et String vide ne sont pas identiques, il faut toujours vérifier les deux conditions.
la source
not null
contrainte sur votre colonne et vérifiez uniquement la chaîne vide.WHERE Field <> ''
renvoie vrai uniquement si le champ n'est pas NULL et n'est pas vide, sur les bases de données avec un comportement ANSI pour les chaînes vides.Selon les documents officiels de 11g
Raisons possibles
val IS NOT NULL
est plus lisible queval != ''
val != '' and val IS NOT NULL
la source
val <> ''
exclut déjàNULL
. Peut-être que vous vouliez direval = '' OR val IS NULL
. Mais les chaînes vides qui ne se comparent pas comme NULL sont utiles !Exemple de livre
la source
Parce que ne pas le traiter comme NULL n'est pas particulièrement utile non plus.
Si vous faites une erreur dans ce domaine sur Oracle, vous le remarquerez généralement immédiatement. Dans SQL Server, cependant, cela semble fonctionner et le problème n'apparaît que lorsque quelqu'un entre une chaîne vide au lieu de NULL (peut-être à partir d'une bibliothèque cliente .net, où null est différent de "", mais vous les traitez généralement de la même manière) ).
Je ne dis pas qu'Oracle a raison, mais il me semble que les deux façons sont à peu près également mauvaises.
la source
En effet, je n'ai eu que des difficultés à traiter avec Oracle, y compris des valeurs datetime invalides (ne peuvent pas être imprimées, converties ou quoi que ce soit, juste regardées avec la fonction DUMP ()) qui sont autorisées à être insérées dans la base de données, apparemment à travers un buggy version du client sous forme de colonne binaire! Voilà pour protéger l'intégrité de la base de données!
Gestion des liens NULL par Oracle:
http://digitalbush.com/2007/10/27/oracle-9i-null-behavior/
http://jeffkemponoracle.com/2006/02/empty-string-andor-null.html
la source
Tout d'abord, les chaînes null et null n'ont pas toujours été traitées de la même manière par Oracle. Une chaîne nulle est, par définition, une chaîne ne contenant aucun caractère. Ce n'est pas du tout la même chose qu'un null. NULL est, par définition, l'absence de données.
Il y a environ cinq ou six ans, la chaîne null était traitée différemment de null par Oracle. Alors que, comme null, la chaîne null était égale à tout et différente de tout (ce qui, je pense, est bien pour null, mais totalement FAUX pour la chaîne null), au moins la longueur (chaîne null) retournerait 0, comme il se doit puisque la chaîne null est une chaîne de longueur nulle.
Actuellement dans Oracle, la longueur (null) renvoie null qui, je suppose, est OK, mais la longueur (chaîne nulle) renvoie également null qui est totalement FAUX.
Je ne comprends pas pourquoi ils ont décidé de commencer à traiter ces 2 "valeurs" distinctes de la même manière. Ils signifient des choses différentes et le programmeur devrait avoir la capacité d'agir sur chacun de différentes manières. Le fait qu'ils aient changé de méthodologie me dit qu'ils n'ont vraiment aucune idée de la façon dont ces valeurs doivent être traitées.
la source
VARCHAR
champ peut avoir une valeur (zéro ou plusieurs caractères) ou aucune valeur (NULL), point final.NULL
valeurs nulles, et il n'y a jamais eu de distinction entre et une chaîne de valeur nulle, et une telle distinction n'a aucun sens. J'ai peur que cette réponse soit un fantasme complet.