web-dev-qa-db-fra.com

Pourquoi Oracle 9i considère-t-il une chaîne vide comme NULL?

Je sais que est-ce que considère '' comme NULL, mais cela ne fait pas grand chose à me dire pourquoi c'est le cas. Si je comprends bien les spécifications SQL, '' n'est pas identique à NULL - l'un 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. Si quelqu'un d'Oracle peut en parler, ce serait fantastique!

206
Chris R

Je crois que la réponse est que Oracle est très, très vieux.

À l'époque jadis avant la mise en place d'un standard SQL, Oracle avait décidé de créer des chaînes vides dans VARCHAR/VARCHAR2 les colonnes étaient NULL et qu’il n’y avait qu’un seul sens NULL (il existe des théoriciens relationnels qui différencieraient des données qui n’ont jamais été invitées, des données pour lesquelles la réponse existe mais que l’utilisateur ne connaît pas, les données où il n'y a pas de réponse, etc., ce qui constitue un certain sens de NULL).

Au moment où la norme SQL est arrivée et a convenu que NULL et la chaîne vide étaient des entités distinctes, il existait déjà des utilisateurs d'Oracle dont le code supposait que les deux étaient équivalents. Donc, Oracle avait essentiellement la possibilité de rompre le code existant, de violer le standard SQL ou d'introduire une sorte de paramètre d'initialisation qui modifierait les fonctionnalités d'un nombre potentiellement important de requêtes. Violer le standard SQL (IMHO) était le moins perturbant de ces trois options.

Oracle a laissé ouverte la possibilité que le type de données VARCHAR change dans une version ultérieure pour respecter le standard SQL (raison pour laquelle tout le monde utilise VARCHAR2 dans Oracle car il est garanti que le comportement de ce type de données restera le même à l'avenir).

208
Justin Cave

Tom Kyte VP d'Oracle:

Une longueur ZERO varchar est traitée comme NULL.

'' n'est pas traité comme NULL.

'' lorsqu'il est affecté à un caractère (1) devient '' (les types de caractère sont des chaînes complétées par des blancs).

'' lorsqu'il est assigné à varchar2 (1) devient '' qui est une chaîne de longueur zéro et une chaîne de longueur zéro est NULL dans Oracle (ce n'est pas long '')

56
Brian

Je suppose que cela a beaucoup plus de sens si vous pensez à Oracle comme le faisaient probablement les développeurs précédents - 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 dans un formulaire qu'un opérateur de saisie de données a vu sur son écran. Si l'opérateur n'a pas tapé quoi que ce soit dans un champ, que ce soit "date de naissance" ou "adresse", les données de ce champ sont "inconnues". Il n’ya aucun moyen pour un opérateur d’indiquer que l’adresse d’une personne est vraiment une chaîne vide, et cela n’a vraiment aucun sens.

19
user67897

La documentation Oracle alerte les développeurs sur ce problème, depuis au moins la version 7.

Oracle a choisi de représenter NULLS par la technique de la "valeur impossible". Par exemple, une valeur NULL dans un emplacement numérique sera stockée sous la forme "moins zéro", une valeur impossible. Tous les zéros qui résultent 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 comme 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 que certaines versions futures d'Oracle pourraient rompre cette association entre la chaîne vide et NULL, ainsi que tout code dépendant de cette association.

Il existe des techniques pour signaler NULLS autres que des valeurs impossibles, mais Oracle ne les a pas utilisées.

(J'utilise le mot "localisation" ci-dessus pour désigner l'intersection d'une ligne et d'une colonne.)

17
Walter Mitty

Une 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.

2
Alex Kreutznaer

Selon les documents officiels 11g

Oracle Database traite actuellement une valeur de caractère avec une longueur égale à zéro comme nulle. Toutefois, il est possible que cela ne soit plus le cas dans les versions à venir et Oracle vous recommande de ne pas traiter les chaînes vides de la même manière que les chaînes null.

Raisons possibles

  1. val IS NOT NULL est plus lisible que val != ''
  2. Pas besoin de vérifier les deux conditions val != '' and val IS NOT NULL
1
Sorter

Exemple de livre

   set serveroutput on;   
    DECLARE
    empty_varchar2 VARCHAR2(10) := '';
    empty_char CHAR(10) := '';
    BEGIN
    IF empty_varchar2 IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_varchar2 is NULL');
    END IF;


    IF '' IS NULL THEN
    DBMS_OUTPUT.PUT_LINE(''''' is NULL');
    END IF;

    IF empty_char IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NULL');
    ELSIF empty_char IS NOT NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NOT NULL');
    END IF;

    END;
0
zloctb