L'instruction SQL Server (2008 ou 2012, en particulier) CASE
évalue-t-elle toutes les conditions WHEN
ou se ferme-t-elle une fois qu'elle trouve une clause WHEN
qui prend la valeur true? Si elle passe par l'ensemble des conditions, cela signifie-t-il que la dernière condition évaluée comme vraie écrase ce que la première condition évaluée comme vraie a fait? Par exemple:
SELECT
CASE
WHEN 1+1 = 2 THEN'YES'
WHEN 1+1 = 3 THEN 'NO'
WHEN 1+1 = 2 THEN 'NO'
END
Le résultat est "OUI", même si la dernière condition quand doit le faire évaluer à "NON". Il semble qu'il se termine une fois qu'il a trouvé la première condition VRAIE. Quelqu'un peut-il s'il vous plaît confirmer si c'est le cas.
• Renvoie l'expression_résultat de la première expression_entrée = lorsque_expression qui est évaluée à VRAI .
Référence http://msdn.Microsoft.com/en-us/library/ms181765.aspx
Il s'agit d'un comportement SQL standard:
Une expression CASE
évalue la première vraie condition.
S'il n'y a pas de véritable condition, il est évalué dans la partie ELSE
.
S'il n'y a pas de véritable condition et pas de partie ELSE
, elle est évaluée à NULL
.
SQL Server effectue généralement l'évaluation des courts-circuits pour les instructions CASE ( SQLFiddle ):
--Does not fail on the divide by zero.
SELECT
CASE
WHEN 1/1 = 1 THEN 'Case 1'
WHEN 2/0 = 1 THEN 'Case 2'
END;
--Fails on the divide by zero.
SELECT
CASE
WHEN 1/1 = 99 THEN 'Case 1'
WHEN 2/0 = 99 THEN 'Case 2'
END;
Il existe cependant plusieurs types d'instructions qui, à partir de SQL Server 2012, ne court-circuitent pas correctement. Voir le lien de ypercube dans les commentaires.
Oracle effectue toujours l'évaluation des courts-circuits . Voir 11.2 Référence du langage SQL . Ou comparez les éléments suivants ( SQLFiddle ):
--Does not fail on the divide by zero.
SELECT
CASE
WHEN 1/1 = 1 THEN 'Case 1'
WHEN 2/0 = 1 THEN 'Case 2'
END
FROM dual;
--Fails on the divide by zero.
SELECT
CASE
WHEN 1/1 = 99 THEN 'Case 1'
WHEN 2/0 = 99 THEN 'Case 2'
END
FROM dual;
Ce même test ne peut pas être fait avec MySQL car il retourne NULL pour une division par zéro. ( SQL Fiddle )
Il semble que MS SQL Server utilise également une évaluation de court-circuit.
Dans le test suivant, j'ai 3 tests. Le premier est toujours vrai, le second échoue sans référencer la table et le troisième échoue uniquement lorsque les données sont prises en compte.
Dans cette exécution particulière, les deux lignes sont renvoyées avec succès. Si je commente le premier QUAND, ou le premier et le deuxième, j'obtiens des échecs.
CREATE TABLE casetest (test varchar(10))
GO
INSERT INTO casetest VALUES ('12345'),('abcdef')
GO
SELECT CASE WHEN LEN(test)>1 THEN test
WHEN 1/0 = 1 THEN 'abc'
WHEN CAST(test AS int) = 1 THEN 'def'
END
FROM casetest
GO
Dans MySQL, il quittera l'instruction case sur la première vraie option. Si vous avez la possibilité de plusieurs valeurs vraies, vous souhaitez placer la réponse préférée plus tôt dans la séquence.
si l'instruction case utilisée dans la condition WHERE
et le premier cas où l'instruction impliquent l'évaluation des valeurs de colonne de la table et que la première ligne de la table ne remplit pas cette condition, l'instruction case passera au cas suivant lorsque déclaration.
declare @tbl table(id int)
insert into @tbl values(1)
insert into @tbl values(2)
insert into @tbl values(3)
--Fails on the divide by zero.
SELECT * FROM @tbl
where CASE
WHEN id = 2 THEN 1 -- first row in table will not satisfy the condition
WHEN 2/0 = 1 THEN 1
ELSE 0
END =1
-- when filter the records to only who will staisfy the first case when condition, it
will not fail on the divide by zero
SELECT * FROM @tbl
where ID=2 and -- first row in table will satisfy the condition
CASE
WHEN id = 2 THEN 1
WHEN 2/0 = 1 THEN 1
ELSE 0
END =1