79 votos

null vs cadena vacía en Oracle

Posible duplicado:
¿Por qué Oracle 9i trata una cadena vacía como NULL?

Tengo una tabla en Oracle 10g llamada TEMP_TABLE con sólo dos columnas - id y description sólo por el bien de la demostración.

La columna id es una clave primaria generada por secuencia de tipo NUMBER(35, 0) not null y la columna DESCRIPTION es un tipo de VARCHAR2(4000) not null .

La estructura básica de la tabla en este caso sería algo como lo siguiente.

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

Después de crear esta tabla, estoy tratando de insertar lo siguiente INSERT comandos alternativamente.

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

Ambos son infructuosos como es obvio porque el not null se aplica a la restricción DESCRIPTION columna.

En ambos casos, Oracle se queja

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

Una cadena vacía se trata como un NULL en Oracle.


Si se me cayera el not null restricción de la DESCRIPTION la estructura básica de la tabla sería la siguiente

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

y los dos INSERT los comandos especificados tendrían éxito. Crearían dos filas, una con un null y otro con una cadena vacía '' en el DESCRIPTION columna de la TEMP_TABLE .

Ahora, si emito lo siguiente SELECT comando,

SELECT * FROM temp_table WHERE description IS NULL;

entonces recupera las dos filas en las que uno tiene un null y el otro tiene una cadena vacía '' en el DESCRIPTION columna.

Lo siguiente SELECT sin embargo, no recupera ninguna fila del TEMP_TABLE

SELECT * FROM temp_table WHERE description='';

Ni siquiera recupera la fila que tiene una cadena vacía en el DESCRIPTION columna.


Presumiblemente, parece que Oracle trata un null y una cadena vacía '' de manera diferente aquí, lo que sin embargo no parece ser el caso del INSERT en la que tanto un null y una cadena vacía '' no se pueden insertar en una columna con un not null restricción. ¿Por qué es así?

100voto

Vaibhav Desai Puntos 1213

Esto se debe a que Oracle cambia internamente las cadenas vacías por NULLs. Oracle simplemente no deja insertar una cadena vacía.

Por otro lado, Sql Server le permitiría hacer lo que está tratando de lograr.

Hay dos soluciones para ello:

  1. Utilice otra columna que indique si el campo "descripción" es válido o no
  2. Utiliza algún valor ficticio para el campo 'descripción' donde quieras que se almacene una cadena vacía. (por ejemplo, establezca el campo como "stackoverflowrocks" asumiendo que sus datos reales nunca encontrarán tal valor de descripción)

Ambas cosas son, por supuesto, estúpidas soluciones :)

29voto

DazzaL Puntos 13839

En oracle un varchar2 vacío y un null se tratan igual, y tus observaciones lo demuestran.

cuando escribes:

select * from table where a = '';

es lo mismo que escribir

select * from table where a = null;

y no a is null

que nunca será igual a true, por lo que nunca devolverá una fila. lo mismo en la inserción, un NOT NULL significa que no puedes insertar un null o una cadena vacía (que se trata como un null)

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X