null vs chaîne vide dans Oracle

Duplication 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 et description juste pour la démonstration.

L’ id colonne 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 table de base dans ce cas ressemblerait à ce qui suit.

 +--------------+-----------+---------------+ |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 échouent, 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 laissais tomber la contrainte not null sur la colonne DESCRIPTION , la structure de base de la table ressemblerait à ceci

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

et les deux commandes INSERT spécifiées seraient réussies. Ils créeraient deux lignes une avec une valeur null et une autre avec une chaîne vide '' dans la colonne DESCRIPTION de TEMP_TABLE .

Maintenant, si SELECT commande SELECT suivante,

 SELECT * FROM temp_table WHERE description IS NULL; 

puis il récupère les deux lignes dans lesquelles on a une valeur null et l’autre a une chaîne vide '' dans la colonne DESCRIPTION .

L’instruction SELECT suivante ne récupère cependant aucune ligne de 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 la colonne DESCRIPTION .


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

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

D’autre part, SQL Server vous permet de faire ce que vous essayez de réaliser.

Il y a 2 solutions de contournement ici:

  1. Utilisez une autre colonne indiquant si le champ “description” est valide ou non
  2. Utilisez une valeur fictive pour le champ “description” où vous souhaitez stocker une chaîne vide. (c.-à-d. définir 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 stupides 🙂

Dans oracle, un varchar2 et un vide vides 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 qu’écrire

 select * from table where a = null; 

et non a is null

qui ne sera jamais égal à vrai, donc ne jamais retourner une ligne. même sur l’insert, un NOT NULL signifie que vous ne pouvez pas insérer une chaîne vide ou vide (qui est traitée comme une valeur null)