I SQL Server er ANSI_NULLS
indstilling giver dig mulighed for at angive, hvordan NULL
værdier behandles i forespørgsler.
Mere specifikt giver det dig mulighed for at angive ISO-kompatibel adfærd for Equals (=
) og Ikke lig med (<> ) sammenligningsoperatorer, når de bruges med
NULL
værdier.
ANSI_NULLS
kan indstilles til ON
eller OFF
. En NULL
test, der returnerer sand med ANSI_NULLS OFF
kan faktisk returnere falsk med ANSI_NULLS TIL
.
Dette kan være kilden til megen forvirring, og derfor betaler det sig at forstå præcis, hvordan ANSI_NULLS
arbejder.
ANSI_NULLS
indstillinger kan indstilles på databaseniveau og på sessionsniveau. Hvis en ANSI_NULLS
indstillingen på sessionsniveauet ikke er angivet, vil SQL Server bruge hvilken som helst ANSI_NULLS
indstilling anvendes på den aktuelle database. Derfor kan du tilsidesætte databaseindstillingen med din egen sessionsniveauindstilling, når du skriver ad hoc-forespørgsler.
En vigtig ting at bemærke er, at SQL Server Native Client ODBC-driveren og SQL Server Native Client OLE DB Provider til SQL Server automatisk indstiller ANSI_NULLS
til ON
ved tilslutning. Denne indstilling kan konfigureres i ODBC-datakilder, i ODBC-forbindelsesattributter eller i OLE DB-forbindelsesegenskaber, der er indstillet i applikationen, før der oprettes forbindelse til en forekomst af SQL Server.
Sådan tjekker du din sessions ANSI_NULLS-indstilling
Du kan bruge SESSIONPROPERTY()
funktion for at kontrollere ANSI_NULLS
indstilling for den aktuelle session.
SELECT SESSIONPROPERTY('ANSI_NULLS');
Resultat:
+--------------------+ | (No column name) | |--------------------| | 1 | +--------------------+
I dette tilfælde er ANSI_NULLS
indstillingen for min session er ON
.
Et nul (0
) ville betyde, at den er slukket.
Sådan ændrer du din sessions ANSI_NULLS-indstilling
Du kan indstille din sessions ANSI_NULLS-indstilling til OFF
med følgende kode:
SET ANSI_NULLS OFF;
Hvis du derefter tjekker det igen, fremkommer et nul.
SELECT SESSIONPROPERTY('ANSI_NULLS');
Resultat:
+--------------------+ | (No column name) | |--------------------| | 0 | +--------------------+
Standardværdien for SET ANSI_NULLS
er OFF
. Som nævnt ovenfor indstiller SQL Server Native Client ODBC-driveren og SQL Server Native Client OLE DB Provider til SQL Server automatisk ANSI_NULLS
til ON
ved tilslutning.
Eksempler på hvordan ANSI_NULLS
Påvirker forespørgsler
Her er nogle grundlæggende eksempler for at demonstrere de forskellige resultater, du kan få, afhængigt af værdien af ANSI_NULLS
indstilling.
Disse bruger SET ANSI_NULLS
for at skifte ANSI_NULLS
indstilling for den aktuelle session.
ANSI_NULLS TIL
SET ANSI_NULLS ON;
SELECT NULL
WHERE NULL = NULL;
Resultat:
(0 rows affected)
Når ANSI_NULLS
er ON
, alle sammenligninger mod en NULL
værdi evalueres til UNKNOWN
.
I dette tilfælde kan vi ikke rigtig sige det NULL
er lig med NULL
fordi hver værdi er ukendt.
Derfor returneres ingen rækker for ovenstående forespørgsel.
ANSI_NULLS FRA
SET ANSI_NULLS OFF;
SELECT NULL
WHERE NULL = NULL;
Resultat:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+
Når ANSI_NULLS
er OFF
, sammenligninger af alle data mod en NULL
værdi evalueres til TRUE
hvis dataværdien er NULL
.
Den samme logik gælder, når du bruger operatoren Ikke lig med (<> ).
Lad os udvide eksemplet til at inkludere operatoren Ikke lig med (<> ), samt en sammenligning mellem
NULL
og en ikke-NULL
værdi.
ANSI_NULLS TIL
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;
Resultat:
(0 rows affected) (0 rows affected) (0 rows affected) (0 rows affected)
Som forventet returneres ingen rækker for nogen af forespørgslerne. Dette er fordi NULL
værdier behandles som en UKENDT
værdi når ANSI_NULLS
er ON
.
ANSI_NULLS FRA
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;
Resultat:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
Vi får et andet resultat, når ANSI_NULLS
er OFF
.
I dette tilfælde behandler SQL Server ikke NULL
som UKENDT
. Det bestemmer, at NULL
er faktisk lig med NULL
.
Dette er ikke i overensstemmelse med ANSI-standarden.
ER NULL Prædikat
For at et script skal fungere efter hensigten, uanset ANSI_NULLS
databaseindstilling eller indstillingen SET ANSI_NULLS
, brug IS NULL
og ER IKKE NULL
i sammenligninger, der kan indeholde null-værdier
Her er, hvad der sker, når vi omskriver det forrige eksempel til at bruge IS NULL
og ER IKKE NULL
.
ANSI_NULLS TIL
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;
Resultat:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
ANSI_NULLS FRA
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;
Resultat:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
Som forventet får vi det samme resultat uanset ANSI_NULLS
indstilling.
Sammenligningstabel
Følgende tabel skitserer de variationer, du kan få afhængigt af det boolske udtryk og ANSI_NULLS
indstilling.
Boolesk udtryk | INDSTILL ANSI_NULLS TIL | INDSTILL ANSI_NULLS FRA |
---|---|---|
NULL =NULL | UKENDT | SAND |
1 =NULL | UKENDT | FALSK |
NULL <> NULL | UKENDT | FALSK |
1 <> NULL | UKENDT | SAND |
NULL> NULL | UKENDT | UKENDT |
1> NULL | UKENDT | UKENDT |
NULL ER NULL | SAND | SAND |
1 ER NULL | FALSK | FALSK |
NULL ER IKKE NULL | FALSK | FALSK |
1 ER IKKE NULL | SAND | SAND |
Indstilling af ANSI_NULLS på databaseniveau
Hver SQL Server-database har en ANSI_NULLS
indstilling, som bestemmer, hvordan sammenligninger med NULL
værdier evalueres.
- Når den er indstillet til
ON
, sammenligninger med enNULL
værdi evalueres tilUNKNOWN
. - Når den er indstillet til
OFF
, sammenligninger af ikke-Unicode-værdier med enNULL
værdi evalueres tilTRUE
hvis begge værdier erNULL
.
Du kan ændre denne indstilling på en database med følgende kode:
ALTER DATABASE CURRENT
SET ANSI_NULLS ON;
Det sætter ANSI_NULLS
til ON
for den aktuelle database. Du kan bytte CURRENT
med navnet på en database, hvis det foretrækkes.
Du kan kontrollere den aktuelle indstilling med DATABASEPROPERTYEX()
funktion.
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullsEnabled');
Resultat:
1
Som nævnt kan du tilsidesætte denne indstilling, når du skriver ad hoc-forespørgsler ved at indstille den på sessionsniveau, som vi gjorde tidligere.
Mens vi er ved emnet, bør jeg nævne, at SQL Server-databaser også har en ANSI_NULL_DEFAULT
indstilling. Denne indstilling bestemmer standardværdien, NULL
eller IKKE NULL
, af en kolonne eller CLR brugerdefineret type, for hvilken nullabiliteten ikke er eksplicit defineret i CREATE TABLE
eller ÆNDRINGSTABEL
udsagn.
Denne værdi kan indstilles således:
ALTER DATABASE CURRENT
SET ANSI_NULL_DEFAULT ON;
Dens værdi kan hentes på denne måde:
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullDefault');
Resultat:
1
Du kan også bruge sys.databases
katalogvisning for at returnere disse indstillinger for alle databaser.
SELECT
name,
is_ansi_nulls_on,
is_ansi_null_default_on
FROM sys.databases
ORDER BY name ASC;