web-dev-qa-db-fra.com

Dans SQL Server, que signifie "SET ANSI_NULLS ON"?

La définition dit:

Lorsque SET ANSI_NULLS est activé, une instruction SELECT qui utilise WHERE nom_colonne = NULL ne renvoie aucune ligne, même s'il existe des valeurs null dans nom_colonne. Une instruction SELECT qui utilise WHERE nom_colonne <> NULL ne renvoie aucune ligne, même s'il existe des valeurs non nulles dans nom_colonne.

Cela signifie-t-il qu'aucune valeur NULL ne sera incluse dans cette requête?

SELECT Region
FROM employees
WHERE Region = @region

Ou faire ANSI_NULL _ ne concerne que les requêtes comme celle-ci (où WHERE inclut le mot spécifique NULL)?

SELECT Region
FROM employees
WHERE Region = NULL
75
Rodniko

Cela signifie qu'aucune ligne ne sera retournée si @region est NULL, lorsqu'il est utilisé dans votre premier exemple, même s'il existe des lignes dans la table où Region est NULL.

Quand ANSI_NULLS est activé (vous devez toujours le définir car l’option de ne pas l’avoir activée sera supprimée dans le futur), toute opération de comparaison où (au moins) l’un des opérandes est NULL produit la troisième valeur logique - UNKNOWN (par opposition à TRUE et FALSE).

Les valeurs UNKNOWN se propagent à travers les opérateurs booléens qui combinent si elles ne sont pas déjà décidées (par exemple AND avec un opérande FALSE ou OR avec un TRUE opérande) ou des négations (NOT).

La clause WHERE sert à filtrer le jeu de résultats généré par la clause FROM, de sorte que la valeur globale de la clause WHERE doit être TRUE pour la ligne à ne pas filtrer. Ainsi, si une comparaison UNKNOWN est produite, la ligne sera filtrée.


@ (User1227804) réponse inclut cette citation:

Si les deux côtés de la comparaison sont des colonnes ou des expressions composées, le paramètre n'affecte pas la comparaison.

de SET ANSI_NULLS*

Cependant, je ne suis pas sûr du but recherché, car si deux colonnes NULL sont comparées (par exemple dans un JOIN), la comparaison échoue toujours:

create table #T1 (
    ID int not null,
    Val1 varchar(10) null
)
insert into #T1(ID,Val1) select 1,null

create table #T2 (
    ID int not null,
    Val1 varchar(10) null
)
insert into #T2(ID,Val1) select 1,null

select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and t1.Val1 = t2.Val1

La requête ci-dessus renvoie 0 ligne, alors que:

select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and (t1.Val1 = t2.Val1 or t1.Val1 is null and t2.Val1 is null)

Retourne une ligne. Ainsi, même lorsque les deux opérandes sont des colonnes, NULL n’est pas égal à NULL. Et le documentation pour = n'a rien à dire sur les opérandes:

Lorsque vous comparez deux expressions NULL, le résultat dépend du ANSI_NULLS réglage:

Si ANSI_NULLS est réglé sur ON, le résultat est NULL1, conformément à la convention ANSI, selon laquelle une valeur NULL (ou inconnue) n’est pas égale à une autre NULL ou à une valeur inconnue.

Si ANSI_NULLS est réglé sur OFF, le résultat de NULL par rapport à NULL est TRUE.

La comparaison de NULL à une valeur autre que NULL donne toujours lieu à FALSE2.

Cependant, les deux 1 et 2 sont incorrects - le résultat des deux comparaisons est UNKNOWN.


*La signification cryptique de ce texte a finalement été découverte des années plus tard. Cela signifie en réalité que, pour ces comparaisons, le paramètre n'a pas d'effet et agit toujours comme si le paramètre était activé . Aurait été plus clair s'il avait déclaré que SET ANSI_NULLS OFF était le paramètre qui n'a eu aucun effet.

58

Si @Region n'est pas une valeur null (disons @Region = 'South') il ne renverra pas les lignes où le champ Region est null, quelle que soit la valeur de ANSI_NULLS.

ANSI_NULLS ne fera la différence que lorsque la valeur de @Region est null, c’est-à-dire lorsque votre première requête devient essentiellement la seconde.

Dans ce cas, ANSI_NULLS ON ne renverra aucune ligne (car null = null donnera une valeur booléenne inconnue (a.k.a. null)) et ANSI_NULLS OFF retournera toutes les lignes où le champ Region est nul (parce que null = null donnera true)

5
SWeko

SET ANSI_NULLS ON

IT Retourne toutes les valeurs incluant les valeurs NULL dans la table.

SET ANSI_NULLS off

il se termine lorsque les colonnes contiennent des valeurs nulles

2
Joseph Stalin

https://docs.Microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql

Lorsque SET ANSI_NULLS est activé, une instruction SELECT qui utilise WHERE nom_colonne = NULL ne renvoie aucune ligne, même s'il existe des valeurs null dans nom_colonne. Une instruction SELECT qui utilise WHERE nom_colonne <> NULL ne renvoie aucune ligne, même s'il existe des valeurs non nulles dans nom_colonne.

Par exemple

DECLARE @TempVariable VARCHAR(10)
SET @TempVariable = NULL

SET ANSI_NULLS ON
SELECT 'NO ROWS IF SET ANSI_NULLS ON' where    @TempVariable = NULL
-- IF ANSI_NULLS ON , RETURNS ZERO ROWS


SET ANSI_NULLS OFF
SELECT 'THERE WILL BE A ROW IF ANSI_NULLS OFF' where    @TempVariable =NULL
-- IF ANSI_NULLS OFF , THERE WILL BE ROW !
0
Prasanth V J

Si vous définissez ANSI NULLS OFF, NULL = NULL retournera la comparaison. PAR EXEMPLE :

        SET ANSI_NULLS OFF
        select * from sys.tables
        where principal_id = Null

retournera un résultat tel qu'indiqué ci-dessous: zcwInvoiceDeliveryType 744547 NULL zcExpenseRptStatusTrack 2099048 NULL ZCVendorPermissions 2840564 NULL ZCWOrgLevelClientFee 4322525 NULL

Bien que cette requête ne renvoie aucun résultat:

        SET ANSI_NULLS ON 
        select * from sys.tables
        where principal_id = Null
0
ProblemSolver