En la mayoría de las implementaciones SQL (por ejemplo, T-SQL, PL/pgSQL, PL/SQL) están disponibles las construcciones de control: condiciones (IF/CASE), bucles (WHILE/FOR/LOOP), y construcciones para el manejo de errores. Son útiles para automatizar la lógica empresarial en el servidor, por ejemplo, para crear informes complejos, validar reglas de negocio, orquestar procesos ETL y automatizar la respuesta a eventos.
Sin embargo, el uso excesivo de bucles y condiciones complejas dentro de los procedimientos SQL puede llevar a una disminución de la legibilidad y del rendimiento (convirtiendo SQL en "el infierno imperativo" — el efecto procedural hell).
Se recomienda utilizar estas construcciones solo para operaciones que no se pueden implementar mediante el procesamiento basado en conjuntos: por ejemplo, el procesamiento de un solo registro a la vez con lógica dinámica.
CREATE PROCEDURE ProcessOrders AS BEGIN DECLARE @OrderID INT, @Total FLOAT DECLARE OrderCursor CURSOR FOR SELECT OrderID FROM Orders WHERE Status = 'NEW' OPEN OrderCursor FETCH NEXT FROM OrderCursor INTO @OrderID WHILE @@FETCH_STATUS = 0 BEGIN SELECT @Total = SUM(Price) FROM OrderItems WHERE OrderID = @OrderID IF @Total > 10000 UPDATE Orders SET Status='MANUAL_CHECK' WHERE OrderID=@OrderID ELSE UPDATE Orders SET Status='APPROVED' WHERE OrderID=@OrderID FETCH NEXT FROM OrderCursor INTO @OrderID END CLOSE OrderCursor DEALLOCATE OrderCursor END
¿Reemplaza CASE en SELECT a los IF anidados en procedimientos y pueden ser intercambiables?
Respuesta: No. CASE solo se puede utilizar en expresiones SELECT/UPDATE/INSERT — para campos calculados. IF — solo en bloques de control de procedimientos/functions/triggers y no se permite en un SELECT "puro".
Ejemplo:
SELECT CASE WHEN score > 80 THEN 'High' ELSE 'Low' END AS Level FROM students -- IF aquí no es posible
Historia
El equipo intentó reescribir todo el proceso empresarial desde el código a procedimientos SQL con abundancia de IF/ELSE anidados y bucles. El resultado: código confuso, no depurable, casi imposible de soportar. Pasaron a trasladar la lógica de vuelta a la aplicación, dejando solo procedimientos críticos.
Historia
En PL/pgSQL, debido al uso incorrecto de LOOP sin una salida correcta (EXIT), se formó un ciclo "infinito" en el procedimiento almacenado, bloqueando la conexión a la base de datos. Se resolvió implementando un límite de repeticiones del ciclo y condiciones de salida correctas.
Historia
Error en la lógica del IF anidado en el procedimiento de procesamiento de pedidos: faltaba la construcción ELSE. Algunos pedidos quedaron en un estado incorrecto (NULL), debido a la falta de una validación posterior. Se añadió un ELSE puntual con un comportamiento predeterminado explícito.