Aquí espero aclarar mi posición.
Que NULL = NULL
evaluar a FALSE
está mal. Hacker y Mister respondieron correctamente NULL
. Aquí es por qué. Dewayne Christensen me escribió, en un comentario a Scott Ivey :
Como es diciembre, usemos un ejemplo estacional. Tengo dos regalos debajo del árbol. Ahora, dime si tengo dos de lo mismo o no.
Pueden ser diferentes o pueden ser iguales, no se sabe hasta que uno abre ambos regalos. ¿Quién sabe? Invitaste a dos personas que no se conocen y ambas te han hecho el mismo regalo: raro, pero no imposible § .
Entonces, la pregunta: ¿estos dos DESCONOCIDOS presentan lo mismo (igual, =)? La respuesta correcta es: DESCONOCIDA (es decir NULL
).
Este ejemplo tenía la intención de demostrar que ".. ( false
o null
, dependiendo de su sistema) .." es una respuesta correcta, no lo es, solo NULL
es correcta en 3VL (¿o está bien que acepte un sistema que da respuestas incorrectas? )
Una respuesta correcta a esta pregunta debe enfatizar estos dos puntos:
- la lógica de tres valores (3VL) es contraintuitiva (vea innumerables preguntas sobre este tema en Stackoverflow y en otro foro para asegurarse);
- Los DBMS basados en SQL a menudo no respetan incluso 3VL, a veces dan respuestas incorrectas (como afirma el póster original, SQL Server lo hace en este caso).
Así que reitero: SQL no sirve para obligar a uno a interpretar la propiedad reflexiva de la igualdad, que establece que:
for any x, x = x
§§ (en inglés simple: cualquiera que sea el universo del discurso, una "cosa" siempre es igual a sí misma ).
.. en un 3VL ( TRUE
, FALSE
, NULL
). La expectativa de las personas se ajustaría a 2VL ( TRUE
, FALSE
que incluso en SQL es válido para todos los demás valores), es decir, x = x
siempre evalúe a TRUE
, para cualquier valor posible de x, sin excepciones.
Tenga en cuenta también que los NULL son " no valores " válidos (como sus apologistas pretenden que son) que se pueden asignar como valores de atributo (??) como parte de las variables de relación. Por lo tanto, son valores aceptables de cada tipo (dominio), no solo del tipo de expresiones lógicas.
Y este fue mi punto :, NULL
como valor, es una "bestia extraña". Sin eufemismo, prefiero decir: sin sentido .
Creo que esta formulación es mucho más clara y menos discutible, lo siento por mi pobre dominio del inglés.
Este es solo uno de los problemas de los NULL. Es mejor evitarlos por completo, cuando sea posible.
§ aquí nos preocupan los valores , por lo que el hecho de que los dos presentes sean siempre dos objetos físicos diferentes no es una objeción válida; si no está convencido de que lo siento, este no es el lugar para explicar la diferencia entre el valor y la semántica de "objeto" (el álgebra relacional tiene una semántica de valor desde el principio; consulte el principio de información de Codd; creo que algunos implementadores de SQL DBMS no ni siquiera se preocupe por una semántica común).
§§ que yo sepa, este es un axioma aceptado (de una forma u otra, pero siempre interpretado en un 2VL) desde la antigüedad y eso exactamente porque es muy intuitivo. 3VL (es una familia de lógicas en realidad) es un desarrollo mucho más reciente (pero no estoy seguro de cuándo se desarrolló por primera vez).
Nota al margen: si alguien presenta los tipos de fondo , unidad y opción como intentos de justificar los NULL de SQL, solo me convenceré después de un examen bastante detallado que mostrará cómo las implementaciones de SQL con NULL tienen un sistema de tipo de sonido y finalmente aclararán qué son NULL (estos "valores-no-valores-realmente") realmente.
En lo que sigue citaré algunos autores. Cualquier error u omisión es probablemente mío y no de los autores originales.
Joe Celko en SQL NULLs
Veo a menudo a Joe Celko citado en este foro. Aparentemente es un autor muy respetado aquí. Entonces, me dije a mí mismo: "¿qué escribió sobre los NULL de SQL? ¿Cómo explica los numerosos problemas de NULL?". Uno de mis amigos tiene una versión de ebook del SQL de Joe Celko para smarties: programación avanzada de SQL, tercera edición . Veamos.
Primero, la tabla de contenido. Lo que más me sorprende es la cantidad de veces que se menciona NULL y en los contextos más variados:
3.4 Aritmética y NULL 109
3.5 Conversión de valores hacia y desde NULL 110
3.5.1 Función NULLIF () 110
6 NULL: datos faltantes en SQL 185
6.4 Comparación de NULL 190
6.5 NULL y lógica 190
6.5.1 NULLS en subconsultas Predicados 191
6.5.2 Estándar Soluciones SQL 193
6.6 Matemáticas y NULL 193
6.7 Funciones y NULL 193
6.8 NULL e idiomas de host 194
6.9 Consejos de diseño para NULL 195
6.9.1 Evitar NULL de los programas de host 197
6.10 Una nota sobre múltiples valores NULL 198
10.1 IS NULL Predicate 241
10.1. 1 Fuentes de NULL 242
...
y así. Suena "desagradable caso especial" para mí.
Voy a entrar en algunos de estos casos con extractos de este libro, tratando de limitarme a lo esencial, por razones de derechos de autor. Creo que estas citas caen dentro de la doctrina del "uso justo" e incluso pueden estimular la compra del libro, por lo que espero que nadie se queje (de lo contrario, tendré que eliminar la mayor parte, si no todas). Además, me abstendré de informar fragmentos de código por el mismo motivo. Lo siento por eso. Compre el libro para leer sobre el razonamiento datailed.
Números de página entre paréntesis en lo que sigue.
Restricción NO NULA (11)
La restricción de columna más importante es NOT NULL, que prohíbe el uso de NULL en una columna. Use esta restricción de forma rutinaria y elimínela solo cuando tenga una buena razón. Le ayudará a evitar las complicaciones de los valores NULL cuando realice consultas contra los datos.
No es un valor ; Es un marcador que contiene un lugar donde puede ir un valor.
Una vez más, este "valor, pero no es un valor" sin sentido. El resto me parece bastante sensato.
(12)
En resumen, los NULL causan muchas características irregulares en SQL, que discutiremos más adelante. Su mejor opción es memorizar las situaciones y las reglas para NULL cuando no puede evitarlas.
A propósito de SQL, NULL e infinito:
(104) CAPÍTULO 3: DATOS NUMÉRICOS EN SQL
SQL no ha aceptado el modelo IEEE para matemáticas por varias razones.
...
Si las reglas IEEE para matemáticas se permitieran en SQL, entonces necesitaríamos reglas de conversión de tipo para infinito y una forma de representar un valor numérico exacto infinito después de la conversión. La gente tiene suficientes problemas con los NULL, así que no vayamos allí.
Las implementaciones de SQL no decidieron qué significa realmente NULL en contextos particulares:
3.6.2 Funciones exponenciales (116)
El problema es que los logaritmos no están definidos cuando (x <= 0). Algunas implementaciones de SQL devuelven un mensaje de error, algunas devuelven un NULL y DB2 / 400; la versión 3 versión 1 devolvió * NEGINF (abreviatura de "infinito negativo") como resultado.
Joe Celko citando a David McGoveran y CJ Fecha:
6 NULL: datos faltantes en SQL (185)
En su libro A Guide to Sybase and SQL Server , David McGoveran y CJ Date dijeron: “Es la opinión de este escritor que los NULL, al menos tal como se definen e implementan actualmente en SQL, son mucho más problemas de lo que valen y deben evitarse; muestran un comportamiento muy extraño e inconsistente y pueden ser una rica fuente de error y confusión. (Tenga en cuenta que estos comentarios y críticas se aplican a cualquier sistema que admita NULL de estilo SQL, no solo a SQL Server específicamente).
NULL como adicción a las drogas :
(186/187)
En el resto de este libro, te instaré a que no los uses , lo que puede parecer contradictorio, pero no lo es. Piense en un NULL como una droga; úsalo correctamente y funciona para ti, pero abusa de él y puede arruinarlo todo. Su mejor política es evitar los NULL cuando pueda y usarlos adecuadamente cuando sea necesario.
Mi única objeción aquí es "usarlos correctamente", que interactúa mal con comportamientos de implementación específicos.
6.5.1 NULOS en predicados de subconsulta (191/192)
La gente olvida que una subconsulta a menudo oculta una comparación con un NULL. Considere estas dos tablas:
...
El resultado estará vacío. Esto es contraintuitivo , pero correcto.
(separador)
6.5.2 Soluciones SQL estándar (193)
SQL-92 resolvió algunos de los problemas de 3VL (lógica de tres valores) al agregar un nuevo predicado de la forma:
<condición de búsqueda> ES [NO] VERDADERO | FALSO | DESCONOCIDO
Pero DESCONOCIDO es una fuente de problemas en sí mismo, por lo que CJ Date, en su libro citado a continuación, recomienda en el capítulo 4.5. Evitar nulos en SQL :
- No use la palabra clave DESCONOCIDO en ningún contexto.
Lea "ASIDE" en UNKNOWN, también vinculado a continuación.
6.8 NULL e idiomas de host (194)
Sin embargo, debe saber cómo se manejan los NULL cuando se tienen que pasar a un programa host. Ningún lenguaje de host estándar para el que se define una incrustación admite NULL, que es otra buena razón para evitar usarlos en el esquema de su base de datos.
(separador)
6.9 Consejos de diseño para NULL (195)
Es una buena idea declarar todas las tablas base con restricciones NOT NULL en todas las columnas siempre que sea posible. Los NULL confunden a las personas que no conocen SQL, y los NULL son caros.
Objeción: NULL confunde incluso a las personas que conocen bien SQL, ver más abajo.
(195)
Deben evitarse los NULL en las CLAVES EXTRANJERAS. SQL permite esta relación de "beneficio de la duda", pero puede causar una pérdida de información en consultas que involucran uniones. Por ejemplo, dado un código de número de pieza en el inventario al que una tabla de pedidos hace referencia como una LLAVE EXTRANJERA, tendrá problemas para obtener una lista de las piezas que tienen un NULL. Esta es una relación obligatoria; No puede pedir una pieza que no existe.
(separador)
6.9.1 Evitar NULL de los programas de host (197)
Puede evitar poner NULL en la base de datos desde los Programas de host con cierta disciplina de programación.
...
- Determine el impacto de los datos faltantes en la programación y los informes: las
columnas numéricas con NULL son un problema, porque las consultas que utilizan funciones agregadas pueden proporcionar resultados engañosos.
(separador)
(227)
La SUMA () de un conjunto vacío siempre es NULL. Uno de los errores de programación más comunes cometidos al usar este truco es escribir una consulta que podría devolver más de una fila. Si no lo pensó, podría haber escrito el último ejemplo como: ...
(separador)
10.1.1 Fuentes de NULL (242)
Es importante recordar dónde pueden ocurrir NULL. Son más que un simple valor posible en una columna . Las funciones agregadas en conjuntos vacíos, OUTER JOIN, expresiones aritméticas con NULL y operadores OLAP devuelven NULL. Estas construcciones a menudo aparecen como columnas en VIEWs.
(separador)
(301)
Otro problema con NULL se encuentra cuando intenta convertir predicados IN a predicados EXISTS.
(separador)
16.3 Las funciones ALL Predicate y Extrema (313)
Al principio es contradictorio que estos dos predicados no sean iguales en SQL:
...
Pero debe recordar las reglas para las funciones extremas: eliminan todos los valores NULL antes de devolver los valores mayores o menores. El predicado ALL no elimina NULL, por lo que puede obtenerlos en los resultados.
(separador)
(315)
Sin embargo, la definición en el estándar está redactada en negativo, de modo que los NULL obtienen el beneficio de la duda. ...
Como puede ver, es una buena idea evitar NULL en restricciones ÚNICAS.
Hablando de GROUP BY:
Los NULL se tratan como si fueran todos iguales y forman su propio grupo. Cada grupo se reduce a una sola fila en una nueva tabla de resultados que reemplaza a la anterior.
Esto significa que para la cláusula GROUP BY NULL = NULL no se evalúa como NULL, como en 3VL, pero se evalúa como TRUE.
El estándar SQL es confuso:
ORDER BY y NULLs (329)
Si un valor de clave de clasificación que es NULL se considera mayor o menor que un valor no NULL está definido por la implementación, pero ...
... Hay productos SQL que lo hacen de cualquier manera.
En marzo de 1999, Chris Farrar planteó una pregunta de uno de sus desarrolladores que le hizo examinar una parte del Estándar SQL que creí haber entendido . Chris encontró algunas diferencias entre la comprensión general y la redacción real de la especificación .
Y así. Creo que es suficiente por Celko.
Fecha de CJ en NULL de SQL
CJ Date es más radical acerca de los NULL: evite los NULL en SQL, punto. De hecho, el capítulo 4 de su Teoría SQL y Relacional: Cómo escribir un código SQL preciso se titula "SIN DUPLICADOS, SIN NULOS", con subcapítulos
"4.4 ¿Qué hay de malo con los nulos?" y "4.5 Evitar nulos en SQL" (siga el enlace: gracias a Google Books, puede leer algunas páginas en línea).
Fabian Pascal en SQL NULLs
De sus problemas prácticos en la gestión de bases de datos: una referencia para el practicante de pensamiento (sin extractos en línea, lo siento):
10.3 Implicaciones prácticas
10.3.1 NULL SQL
... SQL sufre de los problemas inherentes a 3VL, así como de muchas peculiaridades, complicaciones, contra intuición y errores directos [10, 11]; entre ellos están los siguientes:
- Las funciones agregadas (p. Ej., SUM (), AVG ()) ignoran NULL (excepto COUNT ()).
- Una expresión escalar en una tabla sin filas se evalúa incorrectamente como NULL, en lugar de 0.
- La expresión "NULL = NULL" se evalúa como NULL, pero en realidad no es válida en SQL; Sin embargo, ORDER BY trata los NULL como iguales (lo que sea que precedan o sigan valores "normales" se deja al proveedor de DBMS).
- La expresión "x NO ES NULO" no es igual a "NO (x ES NULO)", como es el caso en 2VL.
...
Todos los dialectos SQL implementados comercialmente siguen este enfoque de 3VL y, por lo tanto, no solo exponen estos problemas, sino que también tienen problemas de implementación específicos, que varían según los productos .