empty - cadena nula vs cadena vacía en Oracle
pl sql is empty (2)
Posible duplicado:
¿Por qué Oracle 9i trata una cadena vacía como NULL?
Tengo una tabla en Oracle 10g llamada TEMP_TABLE
con solo dos columnas: id
y description
solo por el bien de la demostración.
El id
columna es una clave primaria generada 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 similar a la siguiente.
+--------------+-----------+---------------+
|Name | Null? | Type |
+--------------+-----------+---------------+
|ID | NOT NULL | NUMBER(35) |
|DESCRIPTION | NOT NULL | VARCHAR2(4000)|
+--------------+-----------+---------------+
Después de crear esta tabla, estoy tratando de insertar los siguientes comandos INSERT
alternativamente.
INSERT INTO temp_table (id, description) VALUES (1, null); ->unsuccessful
INSERT INTO temp_table (id, description) VALUES (2, ''''); ->unsuccessful
Ambos no son tan obvios porque la restricción not null
se aplica en la columna DESCRIPTION
.
En ambos casos, Oracle se queja
ORA-01400: cannot insert NULL into ("WAGAFASHIONDB"."TEMP_TABLE"."DESCRIPTION")
Una cadena vacía se trata como un valor NULL
en Oracle.
Si eliminé la restricción not null
en la columna DESCRIPTION
, entonces la estructura básica de la tabla se vería como la siguiente
+--------------+-----------+---------------+
|Name | Null? | Type |
+--------------+-----------+---------------+
|ID | NOT NULL | NUMBER(35) |
|DESCRIPTION | | VARCHAR2(4000)|
+--------------+-----------+---------------+
y ambos comandos INSERT
como se especificaron tendrían éxito. TEMP_TABLE
dos filas, una con valor null
y otra con una cadena vacía ''''
en la columna DESCRIPTION
de TEMP_TABLE
.
Ahora, si emite el siguiente comando SELECT
,
SELECT * FROM temp_table WHERE description IS NULL;
luego busca las filas en las que uno tiene un valor null
y la otra tiene una cadena vacía ''''
en la columna DESCRIPTION
.
La siguiente instrucción SELECT
, sin embargo, no recupera filas de TEMP_TABLE
SELECT * FROM temp_table WHERE description='''';
Ni siquiera recupera la fila que tiene una cadena vacía en la columna DESCRIPTION
.
Presumiblemente, parece que Oracle trata un valor null
y una cadena vacía ''''
diferente aquí, que sin embargo no parece ser el caso con la INSERT
en la que se impide que se inserten tanto un valor null
como una cadena vacía ''''
una columna con una restricción not null
. ¿Por que es esto entonces?
En Oracle, un varchar2 vacío y un nulo se tratan de la misma manera, y tus observaciones lo muestran.
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 equivaldrá a verdadero, así que nunca devuelva una fila. lo mismo en la inserción, NOT NULL significa que no puede insertar una cadena nula o vacía (que se trata como un valor nulo)
Esto se debe a que Oracle cambia internamente la cadena vacía a valores NULL. Oracle simplemente no permitirá insertar una cadena vacía.
Por otro lado, SQL Server le permite hacer lo que está tratando de lograr.
Hay 2 soluciones alternativas aquí:
- Use otra columna que indique si el campo ''descripción'' es válido o no
- Use algún valor ficticio para el campo ''descripción'' donde quiere que almacene la cadena vacía. (es decir, configure el campo para que sea ''rocks'' suponiendo que sus datos reales nunca encontrarán tal valor de descripción)
Ambos son, por supuesto, soluciones estúpidas :)