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 unNULL
value restituisceUNKNOWN
. - Quando impostato su
OFF
, confronti di valori non Unicode con unNULL
valore restituisceTRUE
se entrambi i valori sonoNULL
.
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;