El bucle WHILE en T-SQL es una estructura de control que permite repetir un bloque de código mientras se cumpla una condición específica.
En la mayoría de lenguajes de programación (Python, C#, Java), los bucles son el pan de cada día. Los usamos para recorrer listas, arrays o procesar archivos.
En SQL Server, la historia es un poco diferente. SQL es un lenguaje orientado a conjuntos. Está diseñado para procesar 1 millón de filas de golpe con una sola instrucción UPDATE o SELECT.
Sin embargo, a veces no queda más remedio que ensuciarse las manos y procesar algo paso a paso. Para estos casos, T-SQL nos ofrece un único tipo de bucle, el bucle WHILE.
Sintaxis Básica
La estructura es muy sencilla: Mientras la condición sea verdadera, el código dentro del bloque BEGIN...END se repetirá.
WHILE Condición
BEGIN
-- Código a repetir
-- ¡IMPORTANTE! Algo debe cambiar aquí para que la condición sea falsa eventualmente
END
- Condición: Es una expresión booleana que se evalúa antes de cada iteración. Si la condición es verdadera (
TRUE), el bloque de código dentro delBEGIN...ENDse ejecuta. Si es falsa (FALSE), el bucle termina. - BEGIN…END: Define el bloque de código que se ejecutará en cada iteración del bucle.
Ejemplo básico
Imaginemos que queremos imprimir los números del 1 al 5 utilizando un bucle WHILE. El código sería el siguiente:
DECLARE @contador INT = 1;
WHILE @contador <= 5
BEGIN
PRINT 'Contador: ' + CAST(@contador AS VARCHAR);
SET @contador = @contador + 1;
END
En este ejemplo:
- Declaramos una variable
@contadore inicializamos su valor en 1. - La condición
@contador <= 5asegura que el bucle se ejecute mientras el valor de@contadorsea menor o igual a 5. - Dentro del bucle, imprimimos el valor actual de
@contadory luego incrementamos su valor en 1 conSET @contador = @contador + 1. - El bucle termina cuando
@contadoralcanza el valor 6.
¡Cuidado con el Bucle Infinito! Si olvidas la línea SET @Contador = @Contador + 1, la condición @Contador <= 5 será siempre verdadera (1 siempre es menor que 5).
Tu script se ejecutará eternamente, consumiendo CPU hasta que lo canceles manualmente (o el servidor se cuelgue 💥). Revisa siempre tu lógica de salida.
Controlando el flujo: BREAK y CONTINUE
A veces necesitamos alterar el comportamiento normal del bucle. Para eso tenemos dos comandos:
Detiene la iteración actual y vuelve inmediatamente al principio del WHILE para evaluar la condición de nuevo, saltándose el código que quedaba por debajo en esa vuelta.
Imagina que queremos procesar solo los números impares.
DECLARE @k INT = 0;
WHILE @k < 10
BEGIN
SET @k = @k + 1;
-- Si es par (el resto de dividir por 2 es 0), lo saltamos
IF @k % 2 = 0
CONTINUE; -- Vuelve arriba, no ejecuta el PRINT
PRINT 'Número impar: ' + CAST(@k AS VARCHAR);
END
Detiene el bucle inmediatamente y salta a la primera línea después del END.
Imagina que buscamos algo y, una vez encontrado, no queremos seguir iterando.
DECLARE @i INT = 1;
WHILE @i <= 100
BEGIN
PRINT @i;
IF @i = 5
BEGIN
PRINT 'Encontrado el 5. ¡Nos vamos!';
BREAK; -- Rompe el bucle aquí mismo
END
SET @i = @i + 1;
END
La gran advertencia: RBAR (Row By Agonizing Row)
En el mundo de SQL Server, existe un término despectivo para el uso excesivo de bucles: RBAR (Row By Agonizing Row).
Imagina que quieres subir el sueldo un 10% a todos los empleados (ejemplo sencillo, pero sirve para demostrar una cosa).
Opción correcta, pensando modo SQL, usando instrucciones de conjuntos de datos. Rápido, un solo hit a la base de datos.
UPDATE Empleados SET Salario = Salario * 1.10;
-- Tiempo: 0.05 segundos para 10.000 filas.
Opción incorrecta, intentar hacerlo como en programación funcional. Hacer un WHILE que recorra la tabla, lea el ID, haga un UPDATE de esa fila, y pase a la siguiente.
-- Pseudocódigo
WHILE (queden filas)
BEGIN
UPDATE Empleados SET Salario ... WHERE ID = @IDActual;
END
-- Tiempo: 15 segundos para 10.000 filas.
Entonces ¿Cuándo usar WHILE?
Los bucles en SQL son lentos porque impiden que el motor optimice la operación en bloque.
- Tareas administrativas: Hacer copias de seguridad de varias bases de datos una a una.
- Lógica procedimental compleja: Cuando lo que tienes que hacer con cada fila es tan complejo (llamar a APIs, lógica condicional extrema) que no cabe en una sola query.
- Generación de datos: Crear datos de prueba (como insertar 1.000 filas dummy).
