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

SQL Server ANSI_NULLS Forklaret

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 en NULL værdi evalueres til UNKNOWN .
  • Når den er indstillet til OFF , sammenligninger af ikke-Unicode-værdier med en NULL værdi evalueres til TRUE hvis begge værdier er NULL .

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;


  1. CONVERT() vs TRY_CONVERT i SQL Server:Hvad er forskellen?

  2. Giv brugertilladelser til alle nye tabeller oprettet i postgresql

  3. Hvordan får jeg ID'et for flere indsatte rækker i MySQL?

  4. Batch-tilstand normalisering og ydeevne