sql >> Base de Datos >  >> RDS >> Sqlserver

SQL Server ANSI_NULLS explicado

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 un NULL valor evaluar a UNKNOWN .
  • Cuando se establece en OFF , comparaciones de valores no Unicode con un NULL valor evaluar a TRUE si ambos valores son NULL .

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;