2012-06-27 3 views
16

Je veux consulter SQL Server ou de court-circuitOU opérateur court-circuit dans SQL Server

code:

DECLARE @tempTable table 
     (
     id int 
    ) 
     INSERT @tempTable(id) values(1) 

     DECLARE @id varchar(10) 
     SET @id = 'x' 
     SELECT * FROM @tempTable WHERE 1=1 OR id = @id --successfully 
     SELECT * FROM @tempTable WHERE @id = 'x' OR id = @id --Exception not Convert 'x' to int 

Pourquoi? 1 = 1 et @ id = 'x' est vrai.

SQL Server ou opérateur: si la fonction de court-circuit

MERCI

+5

Il n'y a aucune garantie ** ** que ce soit sur la façon et quelles parties d'une condition 'de OR' sont évalués en premier (ou grand). T-SQL est ** PAS ** comme C# de cette façon. Vous ** ne pouvez pas ** compter sur un court-circuit booléen. –

+0

'Pourquoi? 1 = 1 et @ id = 'x' est vrai' - c'est ** ou ** en fait, pas ** et **. –

+0

Ici, dans cette valeur INSERT @tempTable (id) (1), INTO est manquant. – vijay

Répondre

14

Dans SQL, il est aucune exigence qu'une clause OU casse tôt. En d'autres termes, il appartient à l'optimiseur de vérifier les deux conditions simultanément. Je ne suis pas un expert dans l'optimiseur MSSQL, mais j'ai vu des cas où l'optimiseur a et n'a pas court-circuité une clause OR.

+0

OU court-circuité est Mes doutes mais mon bureau de codage sql est ((@ id est NULL OR id = id) ET (@name IS NULL OR nom = @ nom)) Je voudrais savoir si le court-circuit Parce que cette efficacité du processus de décision Pour ce faire, il suffit de réutiliser le plan de requête – NotTwoWayStreet

5

Juste trébuché sur cette question, et avait déjà trouvé ce blog-entrée: http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/

Le serveur SQL est libre d'optimiser une requête partout où il le juge opportun, donc dans l'exemple donné dans le billet de blog, vous ne pouvez pas compter sur le court-circuitage.

Cependant, un cas est apparemment documenté pour évaluer dans l'ordre écrit - vérifier les commentaires de ce billet de blog.

-1

mais il est évident que le serveur MS Sql soutient la théorie du court-circuit, afin d'améliorer les performances en évitant un contrôle inutile,

Soutien Exemple:

SELECT 'TEST' 
WHERE 1 = 'A' 

SELECT 'TEST' 
WHERE 1 = 1 OR 1 = 'A' 

Ici, le premier exemple entraînerait en erreur ' La conversion a échoué lors de la conversion de la valeur varchar 'A' en type de données int. '

Alors que le second fonctionne facilement comme la condition 1 = 1 est évalué à TRUE et donc la deuxième condition n'a pas couru du tout.

De plus

SELECT 'TEST' 
WHERE 1 = 0 OR 1 = 'A' 

ici la première condition évaluerait false et donc le SGBD choisiriez la deuxième condition et encore vous obtiendrez l'erreur de conversion comme dans l'exemple ci-dessus.

NOTE: Je LA CONDITION FAUSSE ÉCRIT JUSTE RÉALISER TEMPS LA CONDITION EST ÉTABLIE court-circuité ou SI LES RÉSULTATS D'INTERROGATION EN ERREUR: l'état EXÉCUTÉ, court-circuité CONTRAIRE.

SIMPLE EXPLICATION

Tenir compte,

WHERE 1 = 1 OR 2 = 2 

comme la première condition est de s'évalué à TRUE, son sens pour évaluer la deuxième condition, car son évaluation quelle que soit la valeur ne modifierait pas le résultat Du coup, c'est une bonne opportunité pour Sql Server de sauvegarder le temps d'exécution de la requête en ignorant la vérification ou l'évaluation inutile des conditions.

en cas de « OU » si la première condition est évaluée à TRUE l'ensemble de la chaîne reliée par « OR » serait considéré comme évalué à true sans évaluer les autres. Si la condition 1 est évaluée à la valeur true, toutes les conditions sont remplies jusqu'à ce que la condition N soit ignorée. Dans les mots généralisés à la détermination du premier TRUE, toutes les autres conditions liées par OR seraient ignorées.

Tenir compte de la deuxième condition

WHERE 1 = 0 AND 1 = 1 

comme la première condition est de s'evalutated à FAUX son sens pour évaluer la deuxième condition, car son évaluation quelle que soit la valeur n'affecterait pas le résultat du tout, donc à nouveau C'est une bonne opportunité pour Sql Server de sauvegarder le temps d'exécution de la requête en ignorant la vérification ou l'évaluation inutile des conditions.

en cas de « ET » si la première condition est évaluée à FAUX l'ensemble de la chaîne liée à la « ET » serait considéré comme évalué à FALSE sans évaluer les autres.

condition1 AND condition2 AND ..... conditionN 

si la condition1 est évaluée à FAUX, reposer toutes les conditions jusqu'à conditionN serait sautée. Dans les mots généralisés à la détermination du premier FALSE, toutes les autres conditions liées par et seraient ignorées.

DE CELUI-CI, A PROGRAMMEUR WISE DOIT TOUJOURS PROGRAMMER LA CHAÎNE DES CONDITIONS DE MANIERE QUE, MOINS CHER OU PLUS éliminons CONDITION SEAOG EVALUEE PREMIER, OU ARRANGE LA CONDITION DE MANIERE QUE PEUT PRENDRE AVANTAGE MAXIMUM DE COURT-CIRCUIT

Merci et salutations,

Rk_Hirpara

+3

raison Downvote: toujours tester les choses sur un serveur réel, avec un ensemble de données raisonnables.Par exemple, essayez cette clause where plus réaliste par rapport à un champ de caractères - où isnumeric (fieldname) = 1 ET convert (decimal, fieldname) <= 0 - vous constaterez qu'il subit une erreur de conversion sur les lignes où isnumeric = 0, même si Techniquement, il ne devrait pas avoir besoin d'évaluer la deuxième condition sur de telles lignes. – Jasmine