2009-12-05 3 views
2

On suppose une définition de table dans SQL Server comme suit:Utilisation de colonnes nullable dans une clause WHERE

CREATE TABLE MyTable (
    Id UNIQUEIDENTIFIER NULL, 
    Info VARCHAR(MAX) 
) 

Et une requête:

DECLARE @id UNIQUEIDENTIFIER 
DECLARE @info VARCHAR(MAX) 
IF @id IS NOT NULL 
BEGIN 
    SELECT @info = Info 
    FROM MyTable 
    WHERE Id = @id 
END 

Dans ce cas, l'analyseur statique de code Visual Studio produit le erreur suivant:

Warning : SR0007 : Microsoft.Performance : Nullable columns can cause final results to be evaluated as NULL for the predicate.

Je ne vois pas le problème ici. L'erreur est liée à la performance; MSDN dit que je devrais utiliser ISNULL() - mais une comparaison égale à NULL est toujours faux, non? Ai-je raté quelque chose, ou l'avertissement est-il faux?

+0

[Ignorer cet avertissement. La recommandation est mauvaise pour la performance] (http://stackoverflow.com/questions/7471740/does-wrapping-nullable-columns-in-isnull-cause-table-scans) –

Répondre

3

Je pense qu'il fait référence à la clause WHERE . Il est dit que votre paramètre et votre colonne peuvent tous deux être NULL, auquel cas votre clause WHERE n'évalue plus vrai/faux. En canalisant votre colonne nullable en une colonne qui a toujours une valeur définie (via ISNULL), vous êtes en meilleure forme, en logique.

Here's the Microsoft documentation on that error.

Sur le côté, NULLs font soi-disant requêtes par skosh plus lent.

+0

Aha! C'est où ils sont * les deux * NULL dont il essaie de se plaindre - sauf si je l'exclure avec un IF ou plus de détails dans la clause WHERE, l'analyseur ne le récupère pas Je ne suis pas sûr de ce que vous voulez dire par rapport aux NULL Voulez-vous dire qu'une colonne nullable est plus lente qu'une colonne non-nullable? Ou parlez-vous de ISNULL? – RickNZ

+0

Je prétends qu'une colonne nullable est plus lente à récupérer/gérer qu'une colonne non-nullable.Mais je n'ai rien Pour le remplacer par un grain de sel NULL = D –

-1
IF @id IS NOT NULL 

doit être remplacé par

IF ISNull(@id, -1) <> -1 
+0

@Raj N'est-ce pas exactement la même chose que " Si @id n'est pas nul "? quel est le point de le changer? – dan

+0

Ce code ne sera même pas compilé, car @id est un GUID, pas un INT. – RickNZ

+0

oups, je pensais que id était un nombre entier, désolé. – Raj

1

Je pense que l'analyseur peut tout simplement pas être pris en compte votre instruction IF.

Votre code me semble correct.

+0

Le message se plaint d'une colonne Nullable, pas d'un paramètre Nullable.Aussi, si je change la clause WHERE pour être: 'Id n'est pas NULL et Id = @ id' ou' @id n'est pas NULL et Id = @ id', le message persiste. – RickNZ

-2

@ Raj: "SI isNull (@id, -1) <> -1"

Je ne le ferais pas car il remplace en fait l'entrée de table

+0

Mieux d'avoir cela comme un commentaire à la réponse de @ Raj ... – RickNZ

+0

mais malheureusement, je suis nouveau et n'ai pas assez de points (ou de réputation) pour commenter: (http://stackoverflow.com/faq – ram

0

La comparaison nulle dépend de la configuration.

When SET ANSI_NULLS is ON, all comparisons against a null value evaluate to UNKNOWN

When SET ANSI_NULLS is ON, a SELECT statement that uses WHERE column_name = NULL returns zero rows even if there are null values in column_name. A SELECT statement that uses WHERE column_name <> NULL returns zero rows even if there are no nnull values in column_name.

When SET ANSI_NULLS is OFF, the Equals (=) and Not Equal To (<>) comparison operators do not follow the ISO standard.

C'est from here.

1

Je pense que c'est un faux avertissement - pouvez-vous le supprimer au cas par cas, ou cet avertissement particulier complètement?

Que se passe quand vous faites cela ?:

CREATE TABLE MyTable (
    Id UNIQUEIDENTIFIER NOT NULL, 
    Info VARCHAR(MAX) 
) 
+0

Le remplacer par "NOT NULL" élimine l'avertissement, je finirai probablement par supprimer le message, je veux juste m'assurer de bien comprendre pourquoi cela arrive en premier , et de le signaler si c'est en fait un bug. – RickNZ