Mi opinión sobre esto es que la documentación deja bastante claro que la intención es que CASE deba cortocircuitar. Como Aaron menciona, ha habido varios casos (¡ja!) En los que se ha demostrado que esto no siempre es cierto.
Hasta ahora, todos estos han sido reconocidos como errores y corregidos, aunque no necesariamente en una versión de SQL Server que puede comprar y parchear hoy (el error de plegado constante aún no ha llegado a una actualización acumulativa AFAIK). El nuevo error potencial, originalmente informado por Itzik Ben-Gan, aún no se ha investigado (Aaron o yo lo agregaremos a Connect en breve).
En relación con la pregunta original, hay otros problemas con CASE (y, por lo tanto, COALESCE) en los que se utilizan funciones de efecto secundario o subconsultas. Considerar:
SELECT COALESCE((SELECT CASE WHEN RAND() <= 0.5 THEN 999 END), 999);
SELECT ISNULL((SELECT CASE WHEN RAND() <= 0.5 THEN 999 END), 999);
El formulario COALESCE a menudo devuelve NULL, más detalles en https://connect.microsoft.com/SQLServer/feedback/details/546437/coalesce-subquery-1-may-return-null
Los problemas demostrados con las transformaciones del optimizador y el seguimiento de expresiones comunes significan que es imposible garantizar que CASE se cortocircuite en todas las circunstancias. Puedo concebir casos en los que tal vez ni siquiera sea posible predecir el comportamiento al inspeccionar el resultado del plan de exhibición pública, aunque hoy no tengo una réplica para eso.
En resumen, creo que puede estar razonablemente seguro de que CASE provocará un cortocircuito en general (particularmente si una persona razonablemente experta inspecciona el plan de ejecución, y ese plan de ejecución se 'aplica' con una guía de plan o sugerencias) pero si necesita una garantía absoluta, debe escribir SQL que no incluya la expresión en absoluto.
No es un estado de cosas enormemente satisfactorio, supongo.
CASE
siempre evalúe los circuitos de izquierda a derecha y siempre cortocircuitos )SELECT COALESCE((SELECT CASE WHEN RAND() <= 0.5 THEN 1 END), 1);
- repetir varias veces. Obtendrás aNULL
veces. Inténtalo de nuevo conISNULL
- nunca obtendrásNULL
...