La definición dice:
Cuando SET ANSI_NULLS está en ON, una instrucción SELECT que usa WHERE column_name = NULL devuelve cero filas incluso si hay valores nulos en column_name. Una sentencia SELECT que usa WHERE column_name <> NULL devuelve cero filas incluso si hay valores no nulos en column_name.
¿Significa esto que no se incluirán nulos en esta consulta?
SELECT Region
FROM employees
WHERE Region = @region
¿O se ANSI_NULL
refieren solo a consultas como esta (donde WHERE
incluye la palabra específica NULL
)?
SELECT Region
FROM employees
WHERE Region = NULL
sql
tsql
stored-procedures
Rodniko
fuente
fuente
Respuestas:
Significa que no se devolverán filas si
@region
esNULL
, cuando se usa en su primer ejemplo, incluso si hay filas en la tabla dondeRegion
estáNULL
.Cuando
ANSI_NULLS
está activado (que siempre debe activar de todos modos, ya que la opción de no tenerlo activado se eliminará en el futuro), cualquier operación de comparación en la que (al menos) uno de los operandos seNULL
produce el tercer valor lógico -UNKNOWN
( en contraposición aTRUE
yFALSE
).UNKNOWN
los valores se propagan a través de cualquier combinación de operadores booleanos si aún no están decididos (por ejemplo,AND
con unFALSE
operando oOR
con unTRUE
operando) o negaciones (NOT
).La
WHERE
cláusula se utiliza para filtrar el conjunto de resultados producido por laFROM
cláusula, de modo que el valor total de laWHERE
cláusula debe serTRUE
para que la fila no se filtre. Por lo tanto, siUNKNOWN
se produce un por cualquier comparación, hará que la fila se filtre.La respuesta de @ user1227804 incluye esta cita:
desde *
SET ANSI_NULLS
Sin embargo, no estoy seguro de qué punto está tratando de hacer, ya que si
NULL
se comparan dos columnas (por ejemplo, en aJOIN
), la comparación aún falla:create table #T1 ( ID int not null, Val1 varchar(10) null ) insert into #T1(ID,Val1) select 1,null create table #T2 ( ID int not null, Val1 varchar(10) null ) insert into #T2(ID,Val1) select 1,null select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and t1.Val1 = t2.Val1
La consulta anterior devuelve 0 filas, mientras que:
select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and (t1.Val1 = t2.Val1 or t1.Val1 is null and t2.Val1 is null)
Devuelve una fila. Entonces, incluso cuando ambos operandos son columnas,
NULL
no es igualNULL
. Y la documentación de=
no tiene nada que decir sobre los operandos:Sin embargo, tanto 1 como 2 son incorrectos; el resultado de ambas comparaciones es
UNKNOWN
.* El significado críptico de este texto fue finalmente descubierto años después. Lo que realmente significa es que, para esas comparaciones, la configuración no tiene ningún efecto y siempre actúa como si la configuración estuviera ACTIVADA . Hubiera sido más claro si hubiera dicho que ese
SET ANSI_NULLS OFF
fue el escenario que no tuvo ningún efecto.fuente
Si
@Region
no es unnull
valor (digamos@Region = 'South'
), no devolverá filas donde el campo Región sea nulo, independientemente del valor de ANSI_NULLS.ANSI_NULLS solo marcará la diferencia cuando el valor de
@Region
esnull
, es decir, cuando su primera consulta se convierta esencialmente en la segunda.En ese caso, ANSI_NULLS ON no devolverá ninguna fila (porque
null = null
producirá un valor booleano desconocido (también conocido comonull
)) y ANSI_NULLS OFF devolverá cualquier fila donde el campo Región sea nulo (porquenull = null
cederátrue
)fuente
Si ANSI_NULLS se establece en "ON" y si aplicamos =, <> en el valor de columna NULL mientras escribimos la instrucción select, no devolverá ningún resultado.
Ejemplo
create table #tempTable (sn int, ename varchar(50)) insert into #tempTable values (1, 'Manoj'), (2, 'Pankaj'), (3, NULL), (4, 'Lokesh'), (5, 'Gopal')
ACTIVAR ANSI_NULLS
select * from #tempTable where ename is NULL -- (1 row(s) affected) select * from #tempTable where ename = NULL -- (0 row(s) affected) select * from #tempTable where ename is not NULL -- (4 row(s) affected) select * from #tempTable where ename <> NULL -- (0 row(s) affected)
APAGAR ANSI_NULLS
select * from #tempTable where ename is NULL -- (1 row(s) affected) select * from #tempTable where ename = NULL -- (1 row(s) affected) select * from #tempTable where ename is not NULL -- (4 row(s) affected) select * from #tempTable where ename <> NULL -- (4 row(s) affected)
fuente
WHERE X IS NULL
yWHERE X = NULL
, y cómo ANSI_NULLS afecta el resultado. A pesar de los entusiastas intentos de los votantes en contra, ¡ESTA debería ser la respuesta aceptada!ACTIVAR ANSI_NULLS
IT Devuelve todos los valores incluidos los valores nulos en la tabla
APAGAR ANSI_NULLS
Termina cuando las columnas contienen valores nulos
fuente
Supongo que lo principal aquí es:
Nunca usuario:
@anything = NULL
@anything <> NULL
@anything != null
Siempre usa:
@anything IS NULL
@anything IS NOT NULL
fuente
Establecer ANSI NULLS OFF hará que la comparación NULL = NULL devuelva verdadera. P.EJ :
SET ANSI_NULLS OFF select * from sys.tables where principal_id = Null
devolverá algún resultado como se muestra a continuación: zcwInvoiceDeliveryType 744547 NULL zcExpenseRptStatusTrack 2099048 NULL ZCVendorPermissions 2840564 NULL ZCWOrgLevelClientFee 4322525 NULL
Si bien esta consulta no devolverá ningún resultado:
SET ANSI_NULLS ON select * from sys.tables where principal_id = Null
fuente
https://docs.microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql
Cuando SET ANSI_NULLS está en ON, una instrucción SELECT que usa WHERE column_name = NULL devuelve cero filas incluso si hay valores nulos en column_name. Una sentencia SELECT que usa WHERE column_name <> NULL devuelve cero filas incluso si hay valores no nulos en column_name.
Por ejemplo
DECLARE @TempVariable VARCHAR(10) SET @TempVariable = NULL SET ANSI_NULLS ON SELECT 'NO ROWS IF SET ANSI_NULLS ON' where @TempVariable = NULL -- IF ANSI_NULLS ON , RETURNS ZERO ROWS SET ANSI_NULLS OFF SELECT 'THERE WILL BE A ROW IF ANSI_NULLS OFF' where @TempVariable =NULL -- IF ANSI_NULLS OFF , THERE WILL BE ROW !
fuente