Autovaloración de valor NULL en una tabla

13

Siempre estoy desconcertado con respecto a algún comportamiento misterioso de t-sql, como el siguiente

-- Create table t and insert values.  
use tempdb
CREATE TABLE dbo.t (a INT NULL);  
-- insert 3 values
INSERT INTO dbo.t values (NULL),(0),(1);  
GO  
set ansi_nulls off -- purposely turn off, so we can allow NULL comparison, such as null = null
go
-- expect 3 rows returned but only 2 returned (without null value row)
select * from dbo.t where a = a 

No se trata de cómo recuperar todas las filas de una tabla y tampoco se trata de evitar el uso de ANSI_NULLS.

Solo quiero solicitar algunas ideas de por qué t-sql se comporta así.

jyao
fuente

Respuestas:

13

Este es un comportamiento sorprendente, pero desde la página de MSDN, SET ANSI_NULLSal menos podemos saber que es el comportamiento esperado. Una razón más para nunca usar ANSI_NULLS OFF:

SET ANSI_NULLSafecta una comparación solo si uno de los operandos de la comparación es una variable NULLo un literal NULL. Si ambos lados de la comparación son columnas o expresiones compuestas, la configuración no afecta la comparación.

ypercubeᵀᴹ
fuente
8

Si bien puede que no esté claro como el cristal de la documentación de msdn, creo que encontrará lo siguiente verdadero

"SET ANSI_NULLS ON afecta una comparación solo si uno de los operandos de la comparación es una variable que es NULL o un NULL literal. Si ambos lados de la comparación son columnas o expresiones compuestas, la configuración no afecta la comparación".

Ver esto /programming/2866714/how-does-ansi-nulls-work-in-tsql

Scott Hodgin
fuente
Gracias Scott y ypercube, ambas respuestas son a los puntos de este comportamiento, así que voté a favor de sus respuestas.
jyao
Ypercube fue el primero :)
Scott Hodgin
4

Robert Sheldon en la siguiente publicación de 2015 analiza los comportamientos NULL y por qué a veces (pero no siempre) fallan

https://www.simple-talk.com/sql/t-sql-programming/how-to-get-nulls-horribly-wrong-in-sql-server/

Describe 13 fallas NULL que un programador puede tropezar fácilmente.

Fracaso # 1: No saber lo que significa NULL

Explicación: NULL es un valor no existente, un valor inexistente. No es cero No es una cadena vacía. Un valor no puede ser igual a NULL. No hay dos valores NULL iguales .

Ese es el problema básico, pero asegúrese de leer sobre las otras fallas.

Sí, las versiones anteriores (anteriores a SQL Server 7, creo) se comportaron de manera diferente, más como lo que quieres.

Sin embargo, si busca el problema en Stack Overflow y Stack Exchange, encontrará muchos hilos largos que discuten los problemas.

RLF
fuente
3
Una vez leí la publicación vinculada de Robert Sheldon, pero (en mi humilde opinión) no tiene ninguna teoría o evidencia que explique el comportamiento de mi ejemplo.
jyao
1
"No hay dos valores NULL iguales". Está bien, pero incluso las personas que saben eso esperarían lo contrario cuando ansi nulls está desactivado. Especialmente porque WHERE NULL = NULLrinde verdadero cuando el ajuste es de.
ypercubeᵀᴹ
1

Para agregar a la discusión, la definición de NULL del estándar SQL92 se puede interpretar de manera ambigua. Aquí hay un buen resumen del manejo e interpretación NULL de varios DBMS cortesía de sqlite.org.

DIVULGACIÓN : Recuerdo haber leído sobre la "ambigüedad" de SQL92 de una versión anterior (como hace 6-8 años) de la página sqlite.org vinculada anteriormente, pero esa página se ha actualizado desde entonces.

La respuesta anterior de RLF tiene una buena cita, pero si no estoy de acuerdo con Robert Sheldon es solo porque considero que "algo que no existe" (es decir, un NULL ) es filosófica y semánticamente equivalente en inglés a "algo más que no existe". ". Si tengo que entender la lógica de Sheldon, entonces uno podría declarar que la definición de NULL también es NULL. (Si no existe, ¿cómo podemos definirlo? Espeluznante, ¿eh?)

Veo una variación de la preparación de Russell Paradox ( y un dolor de cabeza). : - \

Pero nuevamente, esta es una discusión sobre la semántica del idioma inglés ( NO SQL) y el debate sobre filosofía pertenece aquí . :-)

pr1268
fuente
PD: Soy nuevo aquí en esta comunidad SE; Si esto se ha discutido hasta la saciedad antes, me disculpo.
pr1268
1
¿Dónde está exactamente la ambigüedad en el estándar?
ypercubeᵀᴹ
@ ypercubeᵀᴹ: Creo que la ambigüedad radica en el intento de "encajar" un 3VL en un booleano. Las uniones de tablas con comparaciones NULL se podrían interpretar de varias maneras diferentes.
pr1268
Estoy de acuerdo con la inconsistencia pero no con la ambigüedad.
ypercubeᵀᴹ
1
@ ypercubeᵀᴹ: Bastante justo ... Solo estaba citando lo que decía una versión anterior de la página sqlite.org que vinculé anteriormente ("SQL92 es ambiguo con respecto al manejo e interpretación NULL" o algo muy similar). Pero no pretendo discutir. Quizás la página sqlite.org era engañosa y / o totalmente incorrecta. Lo que probablemente explica por qué se actualizó.
pr1268