Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Spiegazione ANSI_NULLS di SQL Server

In SQL Server, il ANSI_NULLS l'impostazione consente di specificare come NULL i valori vengono trattati nelle query.

Più specificamente, consente di specificare il comportamento conforme allo standard ISO di Equals (= ) e diverso da (<> ) operatori di confronto quando vengono utilizzati con NULL valori.

ANSI_NULLS può essere impostato su ON o OFF . Un NULL test che restituisce true con ANSI_NULLS OFF potrebbe effettivamente restituire false con ANSI_NULLS ON .

Questo può essere fonte di molta confusione, quindi vale la pena capire esattamente come ANSI_NULLS lavori.

ANSI_NULLS le impostazioni possono essere impostate a livello di database e di sessione. Se un ANSI_NULLS l'impostazione a livello di sessione non è specificata, SQL Server utilizzerà qualsiasi ANSI_NULLS l'impostazione viene applicata al database corrente. Pertanto, puoi sovrascrivere l'impostazione del database con la tua impostazione a livello di sessione quando scrivi query ad hoc.

Una cosa importante da notare è che il driver ODBC di SQL Server Native Client e il provider OLE DB di SQL Server Native Client per SQL Server impostano automaticamente ANSI_NULLS su ON durante la connessione. Questa impostazione può essere configurata nelle origini dati ODBC, negli attributi di connessione ODBC o nelle proprietà di connessione OLE DB impostate nell'applicazione prima della connessione a un'istanza di SQL ServerSQL Server.

Come controllare l'impostazione ANSI_NULLS della tua sessione

Puoi utilizzare SESSIONPROPERTY() funzione per controllare il ANSI_NULLS impostazione per la sessione corrente.

SELECT SESSIONPROPERTY('ANSI_NULLS');

Risultato:

+--------------------+
| (No column name)   |
|--------------------|
| 1                  |
+--------------------+

In questo caso, il ANSI_NULLS l'impostazione per la mia sessione è ON .

Uno zero (0 ) significherebbe che è spento.

Come modificare l'impostazione ANSI_NULLS della sessione

Puoi impostare l'impostazione ANSI_NULLS della tua sessione su OFF con il seguente codice:

SET ANSI_NULLS OFF;

Quindi controllarlo di nuovo produrrà uno zero.

SELECT SESSIONPROPERTY('ANSI_NULLS');

Risultato:

+--------------------+
| (No column name)   |
|--------------------|
| 0                  |
+--------------------+

Il valore predefinito per SET ANSI_NULLS è OFF . Tuttavia, come accennato in precedenza, il driver ODBC di SQL Server Native Client e il provider OLE DB di SQL Server Native Client per SQL Server impostano automaticamente ANSI_NULLS su ON durante la connessione.

Esempi di come ANSI_NULLS Influisce sulle query

Ecco alcuni esempi di base per dimostrare i diversi risultati che puoi ottenere, a seconda del valore di ANSI_NULLS impostazione.

Questi usano SET ANSI_NULLS per attivare il ANSI_NULLS impostazione per la sessione corrente.

ANSI_NULLS ON

SET ANSI_NULLS ON;

SELECT NULL
WHERE NULL = NULL;

Risultato:

(0 rows affected)

Quando ANSI_NULLS è ON , tutti i confronti con un NULL value restituisce UNKNOWN .

In questo caso, non possiamo davvero dire che NULL è uguale a NULL perché ogni valore è sconosciuto.

Pertanto, non vengono restituite righe per la query precedente.

ANSI_NULLS OFF

SET ANSI_NULLS OFF;

SELECT NULL
WHERE NULL = NULL;

Risultato:

+--------------------+
| (No column name)   |
|--------------------|
| NULL               |
+--------------------+

Quando ANSI_NULLS è OFF , confronti di tutti i dati con un NULL valore restituisce TRUE se il valore dei dati è NULL .

La stessa logica si applica quando si utilizza l'operatore Diverso da (<> ).

Espandiamo l'esempio per includere l'operatore Diverso da (<> ), nonché un confronto tra NULL e un non NULL valore.

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;

Risultato:

(0 rows affected)
(0 rows affected)
(0 rows affected)
(0 rows affected)

Come previsto, nessuna riga viene restituita per nessuna delle query. Questo perché NULL i valori sono trattati come un UNKNOWN valore quando ANSI_NULLS è 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;

Risultato:

+--------------------+
| (No column name)   |
|--------------------|
| NULL               |
+--------------------+
(1 row affected)
(0 rows affected)
(0 rows affected)
+--------------------+
| (No column name)   |
|--------------------|
| Not NULL           |
+--------------------+
(1 row affected)

Otteniamo un risultato diverso quando ANSI_NULLS è OFF .

In questo caso, SQL Server non tratta NULL come UNKNOWN . Determina che NULL è infatti uguale a NULL .

Questo non è conforme allo standard ANSI.

Il IS NULL Predicato

Affinché uno script funzioni come previsto, indipendentemente da ANSI_NULLS opzione database o l'impostazione di SET ANSI_NULLS , usa IS NULL e IS NOT NULL nei confronti che potrebbero contenere valori null

Ecco cosa succede quando riscriviamo l'esempio precedente per utilizzare IS NULL e 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;

Risultato:

+--------------------+
| (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;

Risultato:

+--------------------+
| (No column name)   |
|--------------------|
| NULL               |
+--------------------+
(1 row affected)
(0 rows affected)
(0 rows affected)
+--------------------+
| (No column name)   |
|--------------------|
| Not NULL           |
+--------------------+
(1 row affected)

Come previsto, otteniamo lo stesso risultato indipendentemente da ANSI_NULLS impostazione.

Tabella di confronto

La tabella seguente illustra le variazioni che puoi ottenere a seconda dell'espressione booleana e di ANSI_NULLS impostazione.

Espressione booleana IMPOSTA ANSI_NULLS SU DISATTIVA ANSI_NULLS
NULL =NULL SCONOSCIUTO VERO
1 =NULLO SCONOSCIUTO FALSO
NULL <> NULL SCONOSCIUTO FALSO
1 <> NULL SCONOSCIUTO VERO
NULLA> NULLA SCONOSCIUTO SCONOSCIUTO
1> NULLA SCONOSCIUTO SCONOSCIUTO
NULL IS NULL VERO VERO
1 È NULLO FALSO FALSO
NULL NON È NULL FALSO FALSO
1 NON È NULL VERO VERO

Impostazione ANSI_NULLS a livello di database

Ogni database di SQL Server ha un ANSI_NULLS impostazione, che determina la modalità di confronto con NULL vengono valutati i valori.

  • Quando impostato su ON , confronti con un NULL value restituisce UNKNOWN .
  • Quando impostato su OFF , confronti di valori non Unicode con un NULL valore restituisce TRUE se entrambi i valori sono NULL .

Puoi modificare questa impostazione su un database con il seguente codice:

ALTER DATABASE CURRENT
SET ANSI_NULLS ON;

Ciò imposta ANSI_NULLS su ON per il database corrente. Puoi scambiare CURRENT con il nome di un database se preferito.

Puoi controllare l'impostazione corrente con DATABASEPROPERTYEX() funzione.

SELECT DATABASEPROPERTYEX('Music','IsAnsiNullsEnabled');

Risultato:

1

Come accennato, puoi ignorare questa impostazione quando scrivi query ad hoc impostandola a livello di sessione come abbiamo fatto in precedenza.

Mentre siamo sull'argomento, dovrei menzionare che i database di SQL Server hanno anche un ANSI_NULL_DEFAULT collocamento. Questa impostazione determina il valore predefinito, NULL o NOT NULL , di una colonna o di un tipo CLR definito dall'utente per il quale la capacità di valori nulli non è definita in modo esplicito in CREATE TABLE o ALTER TABLE dichiarazioni.

Questo valore può essere impostato in questo modo:

ALTER DATABASE CURRENT
SET ANSI_NULL_DEFAULT ON;

Il suo valore può essere recuperato in questo modo:

SELECT DATABASEPROPERTYEX('Music','IsAnsiNullDefault');

Risultato:

1

Puoi anche usare sys.databases vista catalogo per restituire queste impostazioni per tutti i database.

SELECT
    name,
    is_ansi_nulls_on,
    is_ansi_null_default_on
FROM sys.databases
ORDER BY name ASC;