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:
-
Guardamos en una variable
@numeroPedidosel total de registros de la tablaPedidos. -
Recorremos en el
WHILEtodos los registros gracias al valor de@iteradorque se ira incrementando en cada vuelta del bucle. -
Guardamos en una variable:
@precioRegistroValidarel precio de aquellos productos que no tengan asociado aún unidClientes. -
Comprobamos en el IF, si el precio de
@precioRegistroValidares mayor o igual que 500. Si esTRUE, hacemos unUPDATEdel 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.