LEAVE
LEAVE sale de un bucle o de un bloque BEGIN...END etiquetado. Es el equivalente a break en lenguajes como JavaScript, Java o C. Se usa con LOOP, WHILE, REPEAT y bloques BEGIN...END.
Sintaxis
LEAVE etiqueta;LEAVE en un LOOP
DELIMITER //
CREATE PROCEDURE buscar_primer_caro(IN umbral DECIMAL(10,2))
BEGIN
DECLARE v_id INT;
DECLARE v_nombre VARCHAR(100);
DECLARE v_precio DECIMAL(10,2);
DECLARE v_done INT DEFAULT FALSE;
DECLARE cur CURSOR FOR
SELECT id, nombre, precio FROM productos ORDER BY id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
OPEN cur;
buscar: LOOP
FETCH cur INTO v_id, v_nombre, v_precio;
IF v_done THEN
LEAVE buscar;
END IF;
-- Salir cuando encontramos el primer producto caro
IF v_precio >= umbral THEN
SELECT v_id AS id, v_nombre AS nombre, v_precio AS precio,
'Primer producto encontrado' AS mensaje;
LEAVE buscar;
END IF;
END LOOP buscar;
CLOSE cur;
END //
DELIMITER ;CALL buscar_primer_caro(1500);| id | nombre | precio | mensaje |
|---|---|---|---|
| 6 | Lenovo ThinkPad X1 | 1549.00 | Primer producto encontrado |
LEAVE en un WHILE
DELIMITER //
CREATE PROCEDURE sumar_hasta_limite(IN limite DECIMAL(10,2))
BEGIN
DECLARE v_nombre VARCHAR(100);
DECLARE v_precio DECIMAL(10,2);
DECLARE v_suma DECIMAL(10,2) DEFAULT 0;
DECLARE v_contador INT DEFAULT 0;
DECLARE v_done INT DEFAULT FALSE;
DECLARE cur CURSOR FOR
SELECT nombre, precio FROM productos
WHERE activo = TRUE ORDER BY precio DESC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
OPEN cur;
acumular: WHILE NOT v_done DO
FETCH cur INTO v_nombre, v_precio;
IF v_done THEN
LEAVE acumular;
END IF;
IF v_suma + v_precio > limite THEN
LEAVE acumular;
END IF;
SET v_suma = v_suma + v_precio;
SET v_contador = v_contador + 1;
END WHILE acumular;
CLOSE cur;
SELECT v_contador AS productos,
v_suma AS total,
limite AS presupuesto,
limite - v_suma AS restante;
END //
DELIMITER ;CALL sumar_hasta_limite(5000);| productos | total | presupuesto | restante |
|---|---|---|---|
| 4 | 4947.98 | 5000.00 | 52.02 |
LEAVE en un bloque BEGIN...END
LEAVE puede salir de un bloque etiquetado, no solo de bucles. Esto es útil para implementar salidas tempranas:
DELIMITER //
CREATE PROCEDURE verificar_y_procesar(IN prod_id INT)
BEGIN
DECLARE v_existe INT;
DECLARE v_activo BOOLEAN;
DECLARE v_stock INT;
DECLARE v_nombre VARCHAR(100);
principal: BEGIN
-- Verificar que existe
SELECT COUNT(*) INTO v_existe FROM productos WHERE id = prod_id;
IF v_existe = 0 THEN
SELECT 'Producto no encontrado' AS error;
LEAVE principal;
END IF;
-- Verificar que está activo
SELECT activo, stock, nombre INTO v_activo, v_stock, v_nombre
FROM productos WHERE id = prod_id;
IF v_activo = FALSE THEN
SELECT 'Producto no activo' AS error;
LEAVE principal;
END IF;
-- Verificar stock
IF v_stock = 0 THEN
SELECT 'Producto sin stock' AS error;
LEAVE principal;
END IF;
-- Si llegamos aquí, todo está bien
SELECT v_nombre AS producto, v_stock AS stock, 'OK' AS estado;
END principal;
END //
DELIMITER ;CALL verificar_y_procesar(1);| producto | stock | estado |
|---|---|---|
| iPhone 15 Pro | 45 | OK |
CALL verificar_y_procesar(999);| error |
|---|
| Producto no encontrado |
LEAVE con bucles anidados
DELIMITER //
CREATE PROCEDURE buscar_en_matriz()
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE j INT;
DECLARE encontrado BOOLEAN DEFAULT FALSE;
exterior: LOOP
IF i > 10 THEN
LEAVE exterior;
END IF;
SET j = 1;
interior: LOOP
IF j > 10 THEN
LEAVE interior;
END IF;
IF i * j = 42 THEN
SELECT i AS fila, j AS columna,
CONCAT(i, ' x ', j, ' = 42') AS resultado;
SET encontrado = TRUE;
LEAVE exterior; -- Sale del bucle exterior
END IF;
SET j = j + 1;
END LOOP interior;
SET i = i + 1;
END LOOP exterior;
IF NOT encontrado THEN
SELECT 'No encontrado' AS resultado;
END IF;
END //
DELIMITER ;CALL buscar_en_matriz();| fila | columna | resultado |
|---|---|---|
| 6 | 7 | 6 x 7 = 42 |
Limpieza
DROP PROCEDURE IF EXISTS buscar_primer_caro;
DROP PROCEDURE IF EXISTS sumar_hasta_limite;
DROP PROCEDURE IF EXISTS verificar_y_procesar;
DROP PROCEDURE IF EXISTS buscar_en_matriz;En el siguiente artículo veremos ITERATE, que salta a la siguiente iteración de un bucle.
Escrito por Eduardo Lázaro
