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 unNULLvalue restituisceUNKNOWN. - Quando impostato su
OFF, confronti di valori non Unicode con unNULLvalore restituisceTRUEse 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;