In SQL Server, de ANSI_NULLS
instelling stelt u in staat om te specificeren hoe NULL
waarden worden behandeld in zoekopdrachten.
Meer in het bijzonder kunt u hiermee het ISO-conforme gedrag van de gelijken specificeren (=
) en niet gelijk aan (<>
) vergelijkingsoperatoren wanneer ze worden gebruikt met NULL
waarden.
ANSI_NULLS
kan worden ingesteld op ON
of OFF
. Een NULL
test die true retourneert met ANSI_NULLS OFF
kan feitelijk false retourneren met ANSI_NULLS ON
.
Dit kan de bron van veel verwarring zijn, en daarom loont het om precies te begrijpen hoe ANSI_NULLS
werken.
ANSI_NULLS
instellingen kunnen worden ingesteld op databaseniveau en op sessieniveau. Als een ANSI_NULLS
instelling op sessieniveau niet is opgegeven, gebruikt SQL Server de ANSI_NULLS
instelling wordt toegepast op de huidige database. Daarom kunt u de database-instelling overschrijven met uw eigen sessieniveau-instelling bij het schrijven van ad-hocquery's.
Een belangrijk ding om op te merken is dat het SQL Server Native Client ODBC-stuurprogramma en SQL Server Native Client OLE DB Provider voor SQL Server automatisch ANSI_NULLS
instellen naar ON
bij het aansluiten. Deze instelling kan worden geconfigureerd in ODBC-gegevensbronnen, in ODBC-verbindingskenmerken of in OLE DB-verbindingseigenschappen die zijn ingesteld in de toepassing voordat verbinding wordt gemaakt met een exemplaar van SQL Server.
Hoe u de ANSI_NULLS-instelling van uw sessie kunt controleren
U kunt de SESSIONPROPERTY()
. gebruiken functie om de ANSI_NULLS
. te controleren instelling voor de huidige sessie.
SELECT SESSIONPROPERTY('ANSI_NULLS');
Resultaat:
+--------------------+ | (No column name) | |--------------------| | 1 | +--------------------+
In dit geval is de ANSI_NULLS
instelling voor mijn sessie is ON
.
Een nul (0
) zou betekenen dat het uit staat.
Hoe u de ANSI_NULLS-instelling van uw sessie kunt wijzigen
U kunt de ANSI_NULLS-instelling van uw sessie instellen op OFF
met de volgende code:
SET ANSI_NULLS OFF;
Als je het opnieuw controleert, krijg je een nul.
SELECT SESSIONPROPERTY('ANSI_NULLS');
Resultaat:
+--------------------+ | (No column name) | |--------------------| | 0 | +--------------------+
De standaardwaarde voor SET ANSI_NULLS
is OFF
. Zoals hierboven vermeld, stellen het SQL Server Native Client ODBC-stuurprogramma en SQL Server Native Client OLE DB Provider voor SQL Server automatisch ANSI_NULLS
in. naar ON
bij het verbinden.
Voorbeelden van hoe ANSI_NULLS
Beïnvloedt zoekopdrachten
Hier zijn enkele basisvoorbeelden om de verschillende resultaten te demonstreren die u kunt krijgen, afhankelijk van de waarde van de ANSI_NULLS
instelling.
Deze gebruiken SET ANSI_NULLS
om de ANSI_NULLS
. te wisselen instelling voor de huidige sessie.
ANSI_NULLS ON
SET ANSI_NULLS ON;
SELECT NULL
WHERE NULL = NULL;
Resultaat:
(0 rows affected)
Wanneer ANSI_NULLS
is ON
, alle vergelijkingen tegen een NULL
waarde evalueren tot UNKNOWN
.
In dit geval kunnen we niet echt zeggen dat NULL
is gelijk aan NULL
omdat elke waarde onbekend is.
Daarom worden er geen rijen geretourneerd voor de bovenstaande zoekopdracht.
ANSI_NULLS OFF
SET ANSI_NULLS OFF;
SELECT NULL
WHERE NULL = NULL;
Resultaat:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+
Wanneer ANSI_NULLS
is OFF
, vergelijkingen van alle gegevens tegen een NULL
waarde evalueren tot TRUE
als de gegevenswaarde NULL
is .
Dezelfde logica is van toepassing bij het gebruik van de operator Niet gelijk aan (<>
).
Laten we het voorbeeld uitbreiden met de operator Niet gelijk aan (<>
), evenals een vergelijking tussen NULL
en een niet-NULL
waarde.
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;
Resultaat:
(0 rows affected) (0 rows affected) (0 rows affected) (0 rows affected)
Zoals verwacht, worden er geen rijen geretourneerd voor een van de query's. Dit komt omdat NULL
waarden worden behandeld als een UNKNOWN
waarde wanneer ANSI_NULLS
is 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;
Resultaat:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
We krijgen een ander resultaat als ANSI_NULLS
is OFF
.
In dit geval behandelt SQL Server NULL
niet als UNKNOWN
. Het bepaalt dat NULL
is in feite gelijk aan NULL
.
Dit is niet in overeenstemming met de ANSI-standaard.
De IS NULL
Predikaat
Om een script te laten werken zoals bedoeld, ongeacht de ANSI_NULLS
database-optie of de instelling van SET ANSI_NULLS
, gebruik IS NULL
en IS NOT NULL
in vergelijkingen die null-waarden kunnen bevatten
Dit is wat er gebeurt als we het vorige voorbeeld herschrijven om IS NULL
te gebruiken en 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;
Resultaat:
+--------------------+ | (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;
Resultaat:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
Zoals verwacht krijgen we hetzelfde resultaat, ongeacht de ANSI_NULLS
instelling.
Vergelijkingstabel
De volgende tabel geeft een overzicht van de variaties die u kunt krijgen, afhankelijk van de Booleaanse uitdrukking en ANSI_NULLS
instelling.
Booleaanse uitdrukking | STEL ANSI_NULLS IN | STEL ANSI_NULLS UIT |
---|---|---|
NULL =NULL | ONBEKEND | WAAR |
1 =NULL | ONBEKEND | FALSE |
NULL <> NULL | ONBEKEND | FALSE |
1 <> NULL | ONBEKEND | WAAR |
NULL> NULL | ONBEKEND | ONBEKEND |
1> NULL | ONBEKEND | ONBEKEND |
NULL IS NULL | WAAR | WAAR |
1 IS NULL | FALSE | FALSE |
NULL IS NIET NULL | FALSE | FALSE |
1 IS NIET NULL | WAAR | WAAR |
ANSI_NULLS instellen op databaseniveau
Elke SQL Server-database heeft een ANSI_NULLS
instelling, die bepaalt hoe vergelijkingen met NULL
waarden worden geëvalueerd.
- Indien ingesteld op
ON
, vergelijkingen met eenNULL
waarde evalueren totUNKNOWN
. - Indien ingesteld op
OFF
, vergelijkingen van niet-Unicode-waarden met eenNULL
waarde evalueren totTRUE
als beide waardenNULL
zijn .
U kunt deze instelling op een database wijzigen met de volgende code:
ALTER DATABASE CURRENT
SET ANSI_NULLS ON;
Dat stelt ANSI_NULLS
. in naar ON
voor de huidige database. Je kunt CURRENT
omwisselen met de naam van een database indien gewenst.
U kunt de huidige instelling controleren met de DATABASEPROPERTYEX()
functie.
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullsEnabled');
Resultaat:
1
Zoals eerder vermeld, kunt u deze instelling overschrijven wanneer u ad-hocquery's schrijft door deze op sessieniveau in te stellen zoals we eerder deden.
Nu we het toch over het onderwerp hebben, moet ik vermelden dat SQL Server-databases ook een ANSI_NULL_DEFAULT
hebben instelling. Deze instelling bepaalt de standaardwaarde, NULL
of NOT NULL
, van een door de gebruiker gedefinieerd type kolom of CLR waarvoor de nullabiliteit niet expliciet is gedefinieerd in CREATE TABLE
of ALTER TABLE
verklaringen.
Deze waarde kan als volgt worden ingesteld:
ALTER DATABASE CURRENT
SET ANSI_NULL_DEFAULT ON;
De waarde kan als volgt worden opgehaald:
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullDefault');
Resultaat:
1
U kunt ook de sys.databases
. gebruiken catalogusweergave om deze instellingen voor alle databases te retourneren.
SELECT
name,
is_ansi_nulls_on,
is_ansi_null_default_on
FROM sys.databases
ORDER BY name ASC;