web-dev-qa-db-fra.com

null vs chaîne vide dans Oracle

Duplicate possible:
Pourquoi Oracle 9i traite-t-il une chaîne vide en tant que NULL?

J'ai une table dans Oracle 10g nommée TEMP_TABLE Avec seulement deux colonnes - id et description juste pour des raisons de démonstration.

La colonne id est une clé primaire générée par séquence de type NUMBER(35, 0) not null et la colonne DESCRIPTION est un type de VARCHAR2(4000) not null.

Dans ce cas, la structure de table de base ressemblerait à quelque chose comme ceci.

+--------------+-----------+---------------+
|Name          | Null?     | Type          |
+--------------+-----------+---------------+
|ID            | NOT NULL  | NUMBER(35)    |
|DESCRIPTION   | NOT NULL  | VARCHAR2(4000)|
+--------------+-----------+---------------+

Après avoir créé cette table, j'essaie d'insérer alternativement les commandes INSERT suivantes.

INSERT INTO temp_table (id, description) VALUES (1, null); ->unsuccessful
INSERT INTO temp_table (id, description) VALUES (2, '');   ->unsuccessful

Les deux sont infructueux car évident car la contrainte not null Est appliquée à la colonne DESCRIPTION.

Dans les deux cas, Oracle se plaint

ORA-01400: cannot insert NULL into ("WAGAFASHIONDB"."TEMP_TABLE"."DESCRIPTION")

Une chaîne vide est traitée comme une valeur NULL dans Oracle.


Si je supprimais la contrainte not null Sur la colonne DESCRIPTION, la structure de la table de base ressemblerait à ceci:

+--------------+-----------+---------------+
|Name          | Null?     | Type          |
+--------------+-----------+---------------+
|ID            | NOT NULL  | NUMBER(35)    |
|DESCRIPTION   |           | VARCHAR2(4000)|
+--------------+-----------+---------------+

et les deux commandes INSERT telles que spécifiées réussiraient. Ils créeraient deux lignes, une avec une valeur null et une autre avec une chaîne vide '' Dans la colonne DESCRIPTION de la colonne TEMP_TABLE.

Maintenant, si j’émets la commande SELECT suivante,

SELECT * FROM temp_table WHERE description IS NULL;

puis, il extrait les deux lignes dans lesquelles l'une a une valeur null et l'autre une chaîne vide '' dans la colonne DESCRIPTION.

L’instruction SELECT suivante ne récupère cependant aucune ligne de la commande TEMP_TABLE

SELECT * FROM temp_table WHERE description='';

Il ne récupère même pas la ligne qui a une chaîne vide dans la colonne DESCRIPTION.


Vraisemblablement, il semble qu'Oracle traite différemment une valeur null et une chaîne vide '', Ce qui ne semble toutefois pas être le cas de l'instruction INSERT dans laquelle null valeur et une chaîne vide '' ne peuvent pas être insérées dans une colonne avec une contrainte not null. Pourquoi est-ce?

72
Tiny

En effet, Oracle modifie en interne la chaîne vide en valeurs NULL. Oracle ne veut tout simplement pas laisser insérer une chaîne vide.

D'autre part, SQL Server vous permettrait de faire ce que vous essayez d'atteindre.

Il existe 2 solutions de contournement ici:

  1. Utilisez une autre colonne indiquant si le champ 'description' est valide ou non.
  2. Utilisez une valeur factice pour le champ 'description' où vous voulez qu'il stocke une chaîne vide. (c'est-à-dire, définissez le champ sur 'stackoverflowrocks' en supposant que vos données réelles ne rencontreront jamais une telle valeur de description)

Les deux sont, bien sûr, des solutions de contournement stupides :)

88
Vaibhav Desai

Dans Oracle, varchar2 et null vides sont traités de la même manière, et vos observations le montrent.

quand tu écris:

select * from table where a = '';

c'est la même chose que l'écriture

select * from table where a = null;

et pas a is null

qui ne sera jamais assimilé à true, ne retournez donc jamais une ligne. identique à l'insertion, un NOT NULL signifie que vous ne pouvez pas insérer une chaîne nulle ou vide (qui est traitée comme une valeur nulle)

28
DazzaL