Problema:
CASE es una de las más potentes y más complejas expresiones incorporadas en Transact-SQL. Debido a su nombre, esta expresión es regularmente confundida con la sentencia CASE disponible en otros lenguajes. En SQL Server, el propósito de la expresión CASE es devolver siempre una expresión. No tiene la intención de efectuar un control de flujo, es por eso que no la llamamos instrucción CASE. A continuación, comparto algunos de los puntos que vemos en NUESTROS CURSOS de cómo utilizar mejor una expresión CASE.
Solución:
Hay dos opciones diferentes para la expresión CASE: la expresión CASE «simple», y la expresión CASE de “búsqueda”. La “simple” comienza con una expresión y la compara con cada una de los posibles valores (estos pueden ser expresiones, pero son típicamente constantes o variables):
CASE [input_expression]
WHEN [eval_expression] THEN [output_expression]
…
ELSE [output_expression]
END
La opción de «busqueda» no se inicia con una expresión de entrada, sino que se sumerge directamente en las comparaciones (estas son expresiones completas que pueden ser evaluadas, y no están restringidos a la igualdad):
CASE
WHEN [full_eval_expression] THEN [output_expression]
…
ELSE [output_expression]
END
Inicia 29 de Agosto
Ejemplos:
DECLARE @variable int = 5;
SELECT [simple] = CASE @variable
WHEN 1 THEN ‘One’
WHEN 5 THEN ‘Five’
ELSE ‘Some other number’
END;
SELECT [searched] = CASE
WHEN @variable = 1 THEN ‘One’
WHEN @variable = 5 THEN ‘Five’
ELSE ‘Some other number’
END;
Desde mi punto de vista, encuentro que la variante de “búsqueda” se utiliza más a menudo, ya que es mucho más flexible. Por ejemplo, si quiero comprobar los valores de dos variables, o utilizar cualquier tipo de comparación que no sea la igualdad, puedo hacer esto:
SELECT CASE WHEN @a > 5 OR @b <= 10 THEN c + @a – @b ELSE c – @b + @a END FROM dbo.table;
Cortocircuitos
Ya sea que use la opción “simple” o de “búsqueda”, puedo tener varias cláusulas WHEN, de las cuales sólo una expresión se puede evaluar como verdadera. En la mayoría de los casos, se puede confiar en la secuencialidad y devolver la primera evaluación que se evalúa como verdadera.
También es bueno colocar una cláusula ELSE para asegurarnos que nunca falle nuestra consulta.
DECLARE @i int = 0;
SELECT CASE
WHEN @a = 0 THEN 0
WHEN @a >= 0 THEN +1
WHEN @a < 0 THEN -1
ELSE 1/0
END;
Inicia 29 de Agosto
Donde se puede utilizar CASE
CASE se puede utilizar en cualquier lugar donde una columna, variable, expresión, o constante se pueda utilizar. Todas esas opciones son válidas, como vemos en el siguiente ejemplo:
DECLARE @i int = 1;
SELECT name,
FirstLetter = MAX(CASE
WHEN name LIKE N’S%’ THEN ‘Starts with S’
ELSE ‘Does not start with S’
END)
FROM sys.databases
WHERE CASE @i
WHEN 1 THEN name
ELSE recovery_model_desc END
= CASE @i
WHEN 2 THEN recovery_model_desc
WHEN 5 THEN name
ELSE ‘Some constant’
END
GROUP BY CASE @i WHEN 2 THEN name ELSE REVERSE(name) END
ORDER BY CASE WHEN database_id < 5 THEN database_id END;
Consideraciones para la anidación
Las expresiones CASE se pueden anidar:
DECLARE @tier int = 2;SELECT
CASE WHEN @tier > 1 THEN
CASE WHEN @tier > 2 THEN
CASE WHEN @tier > 3 THEN
CASE WHEN @tier > 4 THEN
CASE WHEN @tier > 5 THEN
‘Awesome’
ELSE ‘Great’ END
ELSE ‘Good’ END
ELSE ‘Acceptable’ END
ELSE ‘Poor’ END
ELSE ‘Invalid’ END;
Pero hay que tener cuidado, dado que se puede convertir en algo complejo rápidamente, especialmente cuando se mezclan tipos de datos, y hay un límite estricto sobre el número de expresiones CASE anidados: 10. Así que la siguiente consulta no es válida:
DECLARE @i int = 1;SELECT
CASE @i WHEN 1 THEN CASE @i WHEN 2 THEN
CASE @i WHEN 3 THEN CASE @i WHEN 4 THEN
CASE @i WHEN 5 THEN CASE @i WHEN 6 THEN
CASE @i WHEN 7 THEN CASE @i WHEN 8 THEN
CASE @i WHEN 9 THEN CASE @i WHEN 10 THEN
CASE @i WHEN 11 THEN ‘Whoopsies’
END END END END END END END END END END END;
No daría el siguiente mensaje de error:
Msg 125, Level 15, State 3, Line 9
Case expressions may only be nested to level 10.
Resumen
La expresión CASE es poderosa, pero tiene algunos matices que a menudo sorprenden a los nuevos usuarios. Si está utilizando expresiones CASE, usted debe familiarizarse con su funcionamiento y, más importante aún, identificar cuando se podrían producir resultados inesperados.