92 votes

null vs chaîne vide dans Oracle

Duplicata possible :
Pourquoi Oracle 9i traite-t-il une chaîne vide comme NULL ?

J'ai une table dans Oracle 10g nommée TEMP_TABLE avec seulement deux colonnes - id y description juste pour le plaisir de la 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 .

La structure de base de la table dans ce cas ressemblerait à ce qui suit.

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

Après avoir créé ce tableau, j'essaie d'insérer ce qui suit INSERT alternativement.

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

Tous deux échouent de manière évidente parce que la not null est appliquée sur le DESCRIPTION colonne.

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 un NULL dans Oracle.


Si j'ai laissé tomber le not null contrainte sur le DESCRIPTION la structure de base de la table serait la suivante

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

et les deux INSERT telles qu'elles ont été spécifiées ont réussi. Elles créent deux lignes, l'une avec un null et une autre avec une chaîne vide '' dans le DESCRIPTION de la colonne TEMP_TABLE .

Maintenant, si je fais ce qui suit SELECT commandement,

SELECT * FROM temp_table WHERE description IS NULL;

alors il récupère les deux lignes dans lesquelles il y a une null et l'autre a une chaîne vide '' dans le DESCRIPTION colonne.

Les éléments suivants SELECT ne récupère cependant aucune ligne de la base de données TEMP_TABLE

SELECT * FROM temp_table WHERE description='';

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


Vraisemblablement, il semble qu'Oracle traite une null et une chaîne vide '' différemment ici, ce qui ne semble cependant pas être le cas avec la INSERT dans laquelle à la fois un null et une chaîne vide '' ne peuvent pas être insérés dans une colonne avec une valeur not null contrainte. Pourquoi en est-il ainsi ?

120voto

Vaibhav Desai Points 1213

Cela est dû au fait qu'Oracle transforme en interne les chaînes vides en valeurs NULL. Oracle ne permet tout simplement pas d'insérer une chaîne vide.

D'un autre côté, SQL Server vous permettrait de faire ce que vous essayez de faire.

Il existe deux solutions de contournement :

  1. Utilisez une autre colonne qui indique si le champ "description" est valide ou non.
  2. Utilisez une valeur fictive pour le champ "description" lorsque vous voulez qu'il stocke une chaîne vide. (par exemple, définissez le champ comme étant "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 :)

34voto

DazzaL Points 13839

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

quand vous écrivez :

select * from table where a = '';

c'est la même chose que d'écrire

select * from table where a = null;

et non a is null

qui ne sera jamais égal à true, donc ne retournera jamais une ligne. De même pour l'insertion, un NOT NULL signifie que vous ne pouvez pas insérer un null ou une chaîne vide (qui est traitée comme un null).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X