En SQL Server, el ANSI_NULLS
configuración le permite especificar cómo NULL
los valores se tratan en las consultas.
Más específicamente, le permite especificar el comportamiento compatible con ISO de Equals (=
) y Distinto de (<>
) operadores de comparación cuando se usan con NULL
valores.
ANSI_NULLS
se puede establecer en ON
o OFF
. Un NULL
prueba que devuelve verdadero con ANSI_NULLS OFF
en realidad podría devolver falso con ANSI_NULLS ON
.
Esto puede ser fuente de mucha confusión, por lo que vale la pena entender exactamente cómo ANSI_NULLS
obras.
ANSI_NULLS
la configuración se puede establecer en el nivel de la base de datos y en el nivel de la sesión. Si un ANSI_NULLS
no se especifica la configuración a nivel de sesión, SQL Server usará cualquier ANSI_NULLS
la configuración se aplica a la base de datos actual. Por lo tanto, puede anular la configuración de la base de datos con su propia configuración de nivel de sesión al escribir consultas ad hoc.
Una cosa importante a tener en cuenta es que el controlador ODBC de SQL Server Native Client y el proveedor OLE DB de SQL Server Native Client para SQL Server configuran automáticamente ANSI_NULLS
a ON
al conectarse. Esta configuración se puede configurar en fuentes de datos ODBC, en atributos de conexión ODBC o en propiedades de conexión OLE DB que se establecen en la aplicación antes de conectarse a una instancia de SQL Server.
Cómo verificar la configuración ANSI_NULLS de su sesión
Puede usar SESSIONPROPERTY()
función para verificar el ANSI_NULLS
configuración para la sesión actual.
SELECT SESSIONPROPERTY('ANSI_NULLS');
Resultado:
+--------------------+ | (No column name) | |--------------------| | 1 | +--------------------+
En este caso, el ANSI_NULLS
la configuración para mi sesión es ON
.
Un cero (0
) significaría que está apagado.
Cómo cambiar la configuración ANSI_NULLS de su sesión
Puede establecer la configuración ANSI_NULLS de su sesión en OFF
con el siguiente código:
SET ANSI_NULLS OFF;
Luego, verificarlo nuevamente producirá un cero.
SELECT SESSIONPROPERTY('ANSI_NULLS');
Resultado:
+--------------------+ | (No column name) | |--------------------| | 0 | +--------------------+
El valor predeterminado para SET ANSI_NULLS
está OFF
. Sin embargo, como se mencionó anteriormente, el controlador ODBC de SQL Server Native Client y el proveedor OLE DB de SQL Server Native Client para SQL Server configuran automáticamente ANSI_NULLS
a ON
al conectarse.
Ejemplos de cómo ANSI_NULLS
Afecta Consultas
Aquí hay algunos ejemplos básicos para demostrar los diferentes resultados que puede obtener, dependiendo del valor de ANSI_NULLS
ajuste.
Estos usan SET ANSI_NULLS
para alternar el ANSI_NULLS
configuración para la sesión actual.
ANSI_NULLS ON
SET ANSI_NULLS ON;
SELECT NULL
WHERE NULL = NULL;
Resultado:
(0 rows affected)
Cuando ANSI_NULLS
está ON
, todas las comparaciones contra un NULL
valor evaluar a UNKNOWN
.
En este caso, no podemos decir verdaderamente que NULL
es igual a NULL
porque cada valor es desconocido.
Por lo tanto, no se devuelven filas para la consulta anterior.
ANSI_NULLS OFF
SET ANSI_NULLS OFF;
SELECT NULL
WHERE NULL = NULL;
Resultado:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+
Cuando ANSI_NULLS
está OFF
, comparaciones de todos los datos contra un NULL
valor evaluar a TRUE
si el valor de los datos es NULL
.
La misma lógica se aplica cuando se usa el operador No es igual a (<>
).
Ampliemos el ejemplo para incluir el operador No es igual a (<>
), así como una comparación entre NULL
y un no NULL
valor.
ANSI_NULLS ON
SET ANSI_NULLS ON;
SELECT NULL
WHERE NULL = NULL;
SELECT 'Not NULL'
WHERE NULL <> NULL;
SELECT NULL
WHERE 1 = NULL;
SELECT 'Not NULL'
WHERE 1 <> NULL;
Resultado:
(0 rows affected) (0 rows affected) (0 rows affected) (0 rows affected)
Como era de esperar, no se devuelven filas para ninguna de las consultas. Esto se debe a que NULL
los valores se tratan como UNKNOWN
valor cuando ANSI_NULLS
está ON
.
ANSI_NULLS OFF
SET ANSI_NULLS OFF;
SELECT NULL
WHERE NULL = NULL;
SELECT 'Not NULL'
WHERE NULL <> NULL;
SELECT NULL
WHERE 1 = NULL;
SELECT 'Not NULL'
WHERE 1 <> NULL;
Resultado:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
Obtenemos un resultado diferente cuando ANSI_NULLS
está OFF
.
En este caso, SQL Server no trata NULL
como UNKNOWN
. Determina que NULL
es de hecho igual a NULL
.
Esto no cumple con el estándar ANSI.
El IS NULL
predicado
Para que un script funcione según lo previsto, independientemente del ANSI_NULLS
opción de base de datos o la configuración de SET ANSI_NULLS
, usa IS NULL
y IS NOT NULL
en comparaciones que pueden contener valores nulos
Esto es lo que sucede cuando reescribimos el ejemplo anterior para usar IS NULL
y IS NOT NULL
.
ANSI_NULLS ON
SET ANSI_NULLS ON;
SELECT NULL
WHERE NULL IS NULL;
SELECT NULL
WHERE NULL IS NOT NULL;
SELECT 'Not NULL'
WHERE 1 IS NULL;
SELECT 'Not NULL'
WHERE 1 IS NOT NULL;
Resultado:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
ANSI_NULLS OFF
SET ANSI_NULLS OFF;
SELECT NULL
WHERE NULL IS NULL;
SELECT NULL
WHERE NULL IS NOT NULL;
SELECT 'Not NULL'
WHERE 1 IS NULL;
SELECT 'Not NULL'
WHERE 1 IS NOT NULL;
Resultado:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
Como era de esperar, obtenemos el mismo resultado independientemente del ANSI_NULLS
ajuste.
Tabla de comparación
La siguiente tabla describe las variaciones que puede obtener según la expresión booleana y ANSI_NULLS
ajuste.
Expresión booleana | ACTIVAR ANSI_NULLS | DESACTIVAR ANSI_NULLS |
---|---|---|
NULO =NULO | DESCONOCIDO | VERDADERO |
1 =NULO | DESCONOCIDO | FALSO |
NULO <> NULO | DESCONOCIDO | FALSO |
1 <> NULO | DESCONOCIDO | VERDADERO |
NULO> NULO | DESCONOCIDO | DESCONOCIDO |
1> NULO | DESCONOCIDO | DESCONOCIDO |
NULO ES NULO | VERDADERO | VERDADERO |
1 ES NULO | FALSO | FALSO |
NULO NO ES NULO | FALSO | FALSO |
1 NO ES NULO | VERDADERO | VERDADERO |
Configuración de ANSI_NULLS a nivel de base de datos
Cada base de datos de SQL Server tiene un ANSI_NULLS
configuración, que determina cómo las comparaciones con NULL
se evalúan los valores.
- Cuando se establece en
ON
, comparaciones con unNULL
valor evaluar aUNKNOWN
. - Cuando se establece en
OFF
, comparaciones de valores no Unicode con unNULL
valor evaluar aTRUE
si ambos valores sonNULL
.
Puede cambiar esta configuración en una base de datos con el siguiente código:
ALTER DATABASE CURRENT
SET ANSI_NULLS ON;
Eso establece ANSI_NULLS
a ON
para la base de datos actual. Puedes intercambiar CURRENT
con el nombre de una base de datos si se prefiere.
Puede verificar la configuración actual con DATABASEPROPERTYEX()
función.
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullsEnabled');
Resultado:
1
Como se mencionó, puede anular esta configuración al escribir consultas ad hoc configurándola en el nivel de sesión como lo hicimos anteriormente.
Ya que estamos en el tema, debo mencionar que las bases de datos de SQL Server también tienen un ANSI_NULL_DEFAULT
entorno. Esta configuración determina el valor predeterminado, NULL
o NOT NULL
, de una columna o tipo CLR definido por el usuario para el que la nulabilidad no está definida explícitamente en CREATE TABLE
o ALTER TABLE
declaraciones.
Este valor se puede establecer así:
ALTER DATABASE CURRENT
SET ANSI_NULL_DEFAULT ON;
Su valor se puede recuperar así:
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullDefault');
Resultado:
1
También puede usar sys.databases
vista de catálogo para devolver esta configuración para todas las bases de datos.
SELECT
name,
is_ansi_nulls_on,
is_ansi_null_default_on
FROM sys.databases
ORDER BY name ASC;