bucle-while-sql

El bucle WHILE en SQL

  • 4 min

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
Copied!
  • 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 del BEGIN...END se 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
Copied!

En este ejemplo:

  • Declaramos una variable @contador e inicializamos su valor en 1.
  • La condición @contador <= 5 asegura que el bucle se ejecute mientras el valor de @contador sea menor o igual a 5.
  • Dentro del bucle, imprimimos el valor actual de @contador y luego incrementamos su valor en 1 con SET @contador = @contador + 1.
  • El bucle termina cuando @contador alcanza 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
Copied!

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
Copied!

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.
Copied!

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.
Copied!

Entonces ¿Cuándo usar WHILE?

Los bucles en SQL son lentos porque impiden que el motor optimice la operación en bloque.

  1. Tareas administrativas: Hacer copias de seguridad de varias bases de datos una a una.
  2. 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.
  3. Generación de datos: Crear datos de prueba (como insertar 1.000 filas dummy).