Sentencia WHILE en Transact SQL

WHILE es una estructura de control de flujo que permite ejecutar sentencias en bucle siempre que la condición que valide sea verdadera (TRUE)

Veamos su funcionamiento con los siguientes ejemplos:

WHILE

El siguiente ejemplo sencillo, muestra un bucle WHILE que valida que mientras @i sea menor o igual que @max, se consulte el valor de @i y se incremente su valor en 1 y así sucesivamente hasta que @i obtenga el valor de 11 y la condición WHILE sea FALSE.

DECLARE @i INT  = 1
DECLARE @max INT = 10

WHILE(@i <= @max)
BEGIN
   SELECT @i
   SET @i = @i +1
END

Para la realización del próximo ejemplo, primero vamos a realizar varios INSERT INTO sobre la tabla Pedidos, cuyos scripts dejamos a continuación:


INSERT INTO Pedidos (idPedidos, producto, descripcionProducto, precio, fechaPedido, numeroProductos, idClientes)
VALUES (9, 'Nevera Balay', 'Electrodoméstico', '1099.95', '2022-09-15', 1, NULL)

INSERT INTO Pedidos (idPedidos, producto, descripcionProducto, precio, fechaPedido, numeroProductos, idClientes)
VALUES (10, 'Smart TV Samsung', 'Televisor', '799', '2022-09-15', 1, NULL)

INSERT INTO Pedidos (idPedidos, producto, descripcionProducto, precio, fechaPedido, numeroProductos, idClientes)
VALUES (11, 'Microondas TEKA', 'Electrodoméstico', '199.95', '2022-09-15', 1, NULL)

Actualmente nuestra tabla Pedidos tiene los siguientes registros:

idPedidos producto descripcionProducto precio fechaPedido numeroProductos totalPrecio idClientes
1 Xiami Mi 11 Smartphone 286,95 2022-07-09 15 4304,25 3
2 Play Station 5 Consola Sony 549,95 2022-07-18 4 2199,8 2
3 Xbox series X Consola Xbox 499,99 2022-01-21 2 999,98 2
4 MacBook Pro M1 Portátil Apple 2449,5 2022-06-20 1 2449,5 1
5 Echo DOT 3 Altavoz Alexa 39,99 2022-09-01 50 1999,5 4
6 Echo DOT 4 Altavoz Alexa 59,99 2022-09-01 50 2999,5 4
7 Nintendo Switch Consola Nintendo 299,99 2022-09-05 3 899,97 5
8 Horno Balay Electrodoméstico 699,55 2022-09-10 2 1399,1 NULL
9 Nevera Balay Electrodoméstico 1099,95 2022-09-15 1 1099,95 NULL
10 Smart TV Samsung Televisor 799 2022-09-15 1 799 NULL
11 Microondas TEKA Electrodoméstico 199,95 2022-09-15 1 199,95 NULL

Pasemos ahora a mostrar el código de ejemplo:

BEGIN
DECLARE @numeroPedidos INT;
SET @numeroPedidos = (SELECT COUNT (1)
                     FROM Pedidos);
PRINT  'Tenemos ' +
       CAST (@numeroPedidos AS NVARCHAR (10)) +
       ' registros en la tabla Pedidos';

DECLARE @iterador INT = 1;
DECLARE @descuento INT = 100;
DECLARE @precioMinDescuento INT = 500;

    WHILE @iterador <= @numeroPedidos
    BEGIN
        BEGIN TRAN;
        PRINT 'Nos encontramos en el registro número: '+
              CAST (@iterador AS NVARCHAR (10))
        DECLARE @precioRegistroValidar FLOAT;
        SET @precioRegistroValidar = (SELECT precio
                                     FROM Pedidos
                                     WHERE idPedidos = @iterador
                                     AND idClientes IS NULL);
        IF @precioRegistroValidar >= @precioMinDescuento
        BEGIN
            UPDATE Pedidos
            SET precio = precio - @descuento
            WHERE idPedidos = @iterador;
            PRINT 'Al registro '+ CAST (@iterador AS NVARCHAR (10)) +
            ' le ha sido aplicado el descuento'
        END
        SET @iterador = @iterador + 1
        COMMIT TRAN;
    END
END

El siguiente ejemplo básicamente aplica un descuento de 100 euros a aquellos productos de la tabla Pedidos con un precio mayor o igual de 500 euros y no tengan vinculado aún un idClientes. Los pasos son los siguientes:

  1. Guardamos en una variable @numeroPedidos el total de registros de la tabla Pedidos.

  2. Recorremos en el WHILE todos los registros gracias al valor de @iterador que se ira incrementando en cada vuelta del bucle.

  3. Guardamos en una variable: @precioRegistroValidar el precio de aquellos productos que no tengan asociado aún un idClientes.

  4. Comprobamos en el IF, si el precio de @precioRegistroValidar es mayor o igual que 500. Si es TRUE, hacemos un UPDATE del precio del registro restándole el descuento de 100.

Una vez ejecutado el bloque de código, podemos comprobar el precio de los siguientes registros afectados:

idPedidos producto descripcionProducto precio fechaPedido numeroProductos totalPrecio idClientes
8 Horno Balay Electrodoméstico 599,55 2022-09-10 2 1199,1 NULL
9 Nevera Balay Electrodoméstico 999,95 2022-09-15 1 999,95 NULL
10 Smart TV Samsung Televisor 699 2022-09-15 1 699 NULL

CONTINUE y BREAK

Las instrucciones CONTINUE y BREAK, nos permiten continuar y paralizar ejecuciones respectivamente, utilizándose a menudo como método de control de las ejecuciones en bucle de las instrucciones WHILE:

DECLARE @i INT  = 1
DECLARE @max INT = 10

WHILE(@i <= @max)
BEGIN
   SELECT @i
   SET @i = @i +1
       IF @i = 7
           BREAK
       ELSE
           CONTINUE
END

En este ejemplo hemos actualizado el código del ejemplo 1, añadiendo las instrucciones CONTINUE y BREAK. El bucle continuará su ejecución normalmente hasta que @i sea igual a 7, donde haremos un BREAK y finalizará la ejecución.

Esto se traduce que la SELECT solo mostrara en consola hasta el 6.