Pregunta

Sé que considera '& nbsp;' como NULL , pero eso no hace mucho para decirme por qué este es el caso. Como entiendo las especificaciones SQL, '& nbsp;' no es lo mismo que NULL : uno es un dato válido y el otro indica la ausencia de esa misma información.

No dude en especular, pero indique si ese es el caso. Si hay alguien de Oracle que pueda comentarlo, ¡sería fantástico!

¿Fue útil?

Solución

Creo que la respuesta es que Oracle es muy, muy antiguo.

En los viejos tiempos antes de que existiera un estándar SQL, Oracle tomó la decisión de diseño de que las cadenas vacías en las columnas VARCHAR / VARCHAR2 eran NULL y que solo había un sentido de NULL (hay teóricos relacionales que diferenciarían entre los datos que nunca se solicitaron, los datos donde existe la respuesta pero no los conoce el usuario, los datos donde no hay respuesta, etc.) de los cuales constituyen algún sentido de NULL ).

En el momento en que llegó el estándar SQL y acordó que NULL y la cadena vacía eran entidades distintas, ya había usuarios de Oracle que tenían un código que asumía que los dos eran equivalentes. Así que, básicamente, Oracle se quedó con las opciones de romper el código existente, violar el estándar SQL o introducir algún tipo de parámetro de inicialización que cambiaría la funcionalidad de un gran número de consultas. Violar el estándar SQL (IMHO) fue la menos disruptiva de estas tres opciones.

Oracle ha dejado abierta la posibilidad de que el tipo de datos VARCHAR cambie en una versión futura para cumplir con el estándar SQL (es por eso que todos usan VARCHAR2 en Oracle desde se garantiza que el comportamiento de ese tipo de datos seguirá siendo el mismo en el futuro).

Otros consejos

Tom Kyte VP de Oracle:

  

Una varchar de longitud CERO se trata como   NULL.

     

'' no se trata como NULL.

     

'' cuando se asigna a un char (1) se convierte en   '' (los tipos de caracteres están en blanco)   instrumentos de cuerda).

     

'' cuando se asigna a varchar2 (1)   se convierte en '' que es una longitud cero   cadena y una cadena de longitud cero es   NULL en Oracle (no es largo '')

Sospecho que esto tiene mucho más sentido si piensa en Oracle como probablemente lo hicieron los desarrolladores anteriores, como un backend glorificado para un sistema de entrada de datos. Cada campo en la base de datos correspondía a un campo en una forma que un operador de ingreso de datos vio en su pantalla. Si el operador no escribió nada en un campo, ya sea " fecha de nacimiento " o " dirección " entonces los datos para ese campo son " desconocidos " ;. No hay forma de que un operador indique que la dirección de alguien es realmente una cadena vacía, y eso no tiene mucho sentido de todos modos.

La documentación de Oracle alerta a los desarrolladores de este problema, y ??se remonta al menos a la versión 7.

Oracle eligió representar NULLS por el " valor imposible " técnica. Por ejemplo, un NULL en una ubicación numérica se almacenará como " menos cero ", un valor imposible. Todos los ceros negativos que resulten de los cálculos se convertirán a cero positivo antes de ser almacenados.

Oracle también eligió, erróneamente, considerar que la cadena VARCHAR de longitud cero (la cadena vacía) es un valor imposible, y una opción adecuada para representar NULL. Resulta que la cadena vacía está lejos de ser un valor imposible. ¡Es incluso la identidad bajo la operación de concatenación de cuerdas!

La documentación de Oracle advierte a los diseñadores y desarrolladores de bases de datos que algunas versiones futuras de Oracle podrían rompa esta asociación entre la cadena vacía y NULL, y rompa cualquier código que dependa de esa asociación.

Existen técnicas para marcar NULLS que no sean valores imposibles, pero Oracle no los usó.

(Estoy usando la palabra "ubicación" para significar la intersección de una fila y una columna.)

La cadena vacía es lo mismo que NULL simplemente porque es el " males menor " en comparación con la situación cuando los dos (cadena vacía y nula) no son lo mismo.

En los idiomas donde NULL y String vacío no son lo mismo, uno siempre debe verificar ambas condiciones.

Según la documentación oficial de 11g

  

Oracle Database actualmente trata un valor de carácter con una longitud de cero como nulo. Sin embargo, esto puede no seguir siendo cierto en futuras versiones, y Oracle recomienda que no trate las cadenas vacías de la misma manera que las nulas.

Posibles motivos

  1. val IS NOT NULL es más legible que val! = ''
  2. No es necesario verificar ambas condiciones val! = '' y val NO ES NULO

Ejemplo del libro

   set serveroutput on;   
    DECLARE
    empty_varchar2 VARCHAR2(10) := '';
    empty_char CHAR(10) := '';
    BEGIN
    IF empty_varchar2 IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_varchar2 is NULL');
    END IF;


    IF '' IS NULL THEN
    DBMS_OUTPUT.PUT_LINE(''''' is NULL');
    END IF;

    IF empty_char IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NULL');
    ELSIF empty_char IS NOT NULL THEN
    DBMS_OUTPUT.PUT_LINE('empty_char is NOT NULL');
    END IF;

    END;

Porque no tratarlo como NULL tampoco es particularmente útil.

Si comete un error en esta área en Oracle, generalmente se da cuenta de inmediato. Sin embargo, en el servidor SQL parecerá que funciona, y el problema solo aparece cuando alguien ingresa una cadena vacía en lugar de NULL (quizás de una biblioteca de cliente .net, donde null es diferente de " " ;, pero generalmente los trata el mismo).

No estoy diciendo que Oracle tenga razón, pero me parece que ambas formas son igualmente malas.

De hecho, no he tenido más que dificultades al tratar con Oracle, incluidos los valores de fecha y hora no válidos (no se pueden imprimir, convertir ni nada, solo se han visto con la función DUMP ()) que están permitidos para ¡Insértese en la base de datos, aparentemente a través de alguna versión defectuosa del cliente como una columna binaria! ¡Tanto para proteger la integridad de la base de datos!

Manejo de Oracle de los enlaces NULL:

http://digitalbush.com/2007/10/ 27 / oracle-9i-null-behavior /

http://jeffkemponoracle.com/2006/02/empty -string-andor-null.html

En primer lugar, las cadenas nulas y nulas no siempre fueron tratadas como las mismas por Oracle. Una cadena nula es, por definición, una cadena que no contiene caracteres. Esto no es en absoluto lo mismo que un nulo. NULL es, por definición, la ausencia de datos.

Hace cinco o seis años, la cadena nula fue tratada de forma diferente a la nula por Oracle. Mientras que, como nulo, la cadena nula era igual a todo y diferente de todo (lo que creo que está bien para nulo, pero totalmente INCORRECTO para la cadena nula), al menos la longitud (cadena nula) devolvería 0, como debería, ya que la cadena nula es una cadena de longitud cero.

Actualmente en Oracle, la longitud (nula) devuelve un valor nulo, que supongo que es O.K., pero la longitud (cadena nula) también devuelve un valor nulo que es totalmente INCORRECTO.

No entiendo por qué decidieron comenzar a tratar estos 2 valores " distintos " lo mismo. Significan cosas diferentes y el programador debe tener la capacidad de actuar en cada una de diferentes maneras. El hecho de que hayan cambiado su metodología me dice que realmente no tienen ni idea de cómo deben tratarse estos valores.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top