REPEAT

El bucle REPEAT ejecuta un bloque de sentencias y luego verifica la condición de salida. La condición se evalúa después de cada iteración con UNTIL, lo que garantiza que el cuerpo se ejecute al menos una vez.

Sintaxis

[etiqueta:] REPEAT
    sentencias;
UNTIL condicion
END REPEAT [etiqueta];

La condición después de UNTIL no lleva punto y coma.

Ejemplo básico

DELIMITER //
 
CREATE PROCEDURE contar_repeat(IN limite INT)
BEGIN
    DECLARE i INT DEFAULT 1;
    DECLARE resultado VARCHAR(500) DEFAULT '';
 
    REPEAT
        SET resultado = CONCAT(resultado, i, ' ');
        SET i = i + 1;
    UNTIL i > limite
    END REPEAT;
 
    SELECT TRIM(resultado) AS numeros;
END //
 
DELIMITER ;
CALL contar_repeat(5);
numeros
1 2 3 4 5

Se ejecuta al menos una vez

A diferencia de WHILE, REPEAT siempre ejecuta el cuerpo al menos una vez:

DELIMITER //
 
CREATE PROCEDURE repeat_una_vez()
BEGIN
    DECLARE i INT DEFAULT 10;
    DECLARE ejecuto VARCHAR(5) DEFAULT 'No';
 
    REPEAT
        SET ejecuto = 'Sí';
        SET i = i + 1;
    UNTIL i >= 5  -- Condición verdadera desde el inicio
    END REPEAT;
 
    SELECT ejecuto AS se_ejecuto, i AS valor_i;
END //
 
DELIMITER ;
CALL repeat_una_vez();
se_ejecutovalor_i
11

Aunque i >= 5 era verdadero desde el inicio, el cuerpo se ejecutó una vez antes de evaluar la condición.

Generar tabla de multiplicar

DELIMITER //
 
CREATE PROCEDURE tabla_multiplicar(IN numero INT)
BEGIN
    DECLARE i INT DEFAULT 1;
 
    DROP TEMPORARY TABLE IF EXISTS tmp_tabla;
    CREATE TEMPORARY TABLE tmp_tabla (
        operacion VARCHAR(20),
        resultado INT
    );
 
    REPEAT
        INSERT INTO tmp_tabla VALUES (
            CONCAT(numero, ' x ', i),
            numero * i
        );
        SET i = i + 1;
    UNTIL i > 10
    END REPEAT;
 
    SELECT * FROM tmp_tabla;
    DROP TEMPORARY TABLE tmp_tabla;
END //
 
DELIMITER ;
CALL tabla_multiplicar(7);
operacionresultado
7 x 17
7 x 214
7 x 321
7 x 428
7 x 535
7 x 642
7 x 749
7 x 856
7 x 963
7 x 1070

REPEAT con cursor

DELIMITER //
 
CREATE PROCEDURE listar_productos_baratos(IN precio_max DECIMAL(10,2))
BEGIN
    DECLARE v_nombre VARCHAR(100);
    DECLARE v_precio DECIMAL(10,2);
    DECLARE v_done INT DEFAULT FALSE;
    DECLARE v_lista VARCHAR(2000) DEFAULT '';
 
    DECLARE cur CURSOR FOR
        SELECT nombre, precio FROM productos
        WHERE precio <= precio_max AND activo = TRUE
        ORDER BY precio;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;
 
    OPEN cur;
 
    REPEAT
        FETCH cur INTO v_nombre, v_precio;
 
        IF NOT v_done THEN
            SET v_lista = CONCAT(v_lista, v_nombre, ' (', v_precio, '), ');
        END IF;
    UNTIL v_done
    END REPEAT;
 
    CLOSE cur;
 
    SELECT TRIM(TRAILING ', ' FROM v_lista) AS productos;
END //
 
DELIMITER ;
CALL listar_productos_baratos(50);

Comparación de bucles

CaracterísticaLOOPWHILEREPEAT
CondiciónExplícita con LEAVEAntes de iterarDespués de iterar con UNTIL
Ejecución mínima0 veces0 veces1 vez
Cuándo usarControl totalCondición previaEjecutar al menos una vez

Limpieza

DROP PROCEDURE IF EXISTS contar_repeat;
DROP PROCEDURE IF EXISTS repeat_una_vez;
DROP PROCEDURE IF EXISTS tabla_multiplicar;
DROP PROCEDURE IF EXISTS listar_productos_baratos;

En el siguiente artículo veremos LEAVE, la sentencia para salir de un bucle o bloque.

Escrito por Eduardo Lázaro