Question

Je travaille sur l'optimisation d'une requête et je me suis souvent demandé si j'avais toujours utilisé l'opérateur OR de SQL. (SQL Server 2000 également)

J'ai une requête où la clause conditionnelle (WHERE) ressemble à ceci:

WHERE (Column1 = @Param1 or Column1 LIKE @Param1 + '%')
AND (@Param2 = '' OR Column2 = @Param2 OR Column2 LIKE @Param2 + '%')

Maintenant, j'ai toujours compris que OR en SQL évaluait les deux expressions. Ainsi, tous les enregistrements évalués true pour l'expression de gauche seraient renvoyés avec tous les enregistrements évalués true sur l'expression de droite. Par exemple:

SELECT * FROM TABLE1
WHERE COL1 = 'Test' OR Col2 = 'Data'

Ceci renverrait tous les enregistrements où COL1 est 'Test', ainsi que tous les enregistrements où Col2 est 'Données'

Dans l'exemple ci-dessus, j'ai modifié la condition Column2 comme suit:

AND(Column2 LIKE ISNULL(@Param2, '') + '%')

Tout à coup, je reçois 0 ligne retournée.

Est-ce que je me suis trompé en ce que OR n'évalue les expressions que jusqu'à ce qu'il trouve un résultat VRAI ou existe-t-il une condition qui ferait en sorte que 2 différent renvoie des résultats différents?

Était-ce utile?

La solution

"OU n'évalue les expressions que si un résultat VRAI a été trouvé"

C’est seulement nécessaire, mais ce n’est pas votre problème (c’est en fait ce qui vous sauvait dans votre cas initial). Vos deux requêtes ne sont pas vraiment équivalentes.

Je pense que vous avez NULL dans la colonne 2, ce qui ne causera jamais (colonne2 LIKE ISNULL (@ Param2, '') + '%') à la valeur true - et dans votre version originale, le @ Param2 = '' masquait ce cas, puisqu'il est vrai (parfois)

Peut-être:

(ISNULL(Column2, '') LIKE ISNULL(@Param2, '') + '%')

N'oubliez pas la logique à trois valeurs pour les valeurs NULL:

TRUE and UNKNOWN: UNKNOWN
TRUE or UNKNOWN: TRUE

FALSE and UNKNOWN: FALSE
FALSE or UNKNOWN: UNKNOWN

Mais je ne suis pas sûr que votre optimisation vous aide vraiment.

Autres conseils

OR n’est pas exhaustif, d’autant plus qu’il est entre parenthèses. Ce que vous avez en plus grand depuis est: WHERE X AND Y . Le fait que X et Y soient eux-mêmes des expressions booléennes qui utilisent un OU n’est pas important: ils sont évalués séparément et les résultats sont ensuite transmis à l’opérateur AND.

[edit]:
En relisant, j'ai peut-être mal compris votre question. Gardant cela à l'esprit, je devrai choisir l'autre réponse, car NULL LIKE '%' renvoie NULL, ce qui est identique à false dans ce cas. Vous pouvez essayer ceci à la place:

COALESCE(Column2,'') LIKE COALESCE(@param2,'') + '%'

Pour votre information, vous pouvez faire des expériences très simples pour vous assurer que toutes les conditions ne sont pas nécessairement évaluées.

Je l'ai fait dans Oracle, mais je suppose que vous obtiendrez un résultat similaire dans SQL Server.

dev> select * from dual where 1=1 or 1/0 = 3;

D
-
X

La condition après l'OR ne doit pas avoir été évaluée car elle provoquerait une erreur de division par zéro.

Ce traitement des opérateurs booléens est généralement appelé "court-circuitage". et, autant que je sache, est assez standard dans les langues modernes. Elle peut également s'appliquer dans une expression AND. Si la première condition est fausse, il est inutile d'évaluer la deuxième condition, car toute l'expression ne peut pas être vraie.

Plus d'infos: http://en.wikipedia.org/wiki/Short-circuit_evaluation

Quoi qu'il en soit, comme l'a dit Cade, votre véritable problème est probablement la mauvaise gestion des valeurs NULL.

MS-SQL évalue le côté gauche en premier et ne procède pas sauf nécessité.

C’est la même chose avec le connecteur AND, le côté gauche sera évalué et si la valeur est false, le droit ne sera pas évalué.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top