Los procedimientos y funciones almacenados no son solo contenedores cómodos para un grupo de consultas. También te permiten implementar una lógica bastante compleja con bifurcaciones y bucles.
En este artículo veremos las principales estructuras de control de flujo: las sentencias condicionales IF y CASE y el bucle WHILE.
La sentencia condicional IF
La sentencia IF permite ejecutar código según se cumpla o no una condición.
Sintaxis de IF
IF condicion THEN
acciones
[ELSEIF condicion THEN
acciones] ...
[ELSE
acciones]
END IF;- [ ]parte opcional
- ...se puede repetir
- condicion
Una expresión lógica, por ejemplo student_age < 18. Se ejecuta la primera rama cuya condición sea verdadera y las demás se omiten.
- acciones
Una o varias sentencias SQL, cada una terminada en ;. Se ejecutan si se elige esta rama.
- ELSEIF
Otra rama con su propia condición. Solo se comprueba si todas las condiciones anteriores son falsas. Puede haber varias ramas así.
Palabra claveOpcional- ELSE
La rama que se ejecuta si ninguna condición ha resultado verdadera.
Palabra claveOpcional
IF condicion THEN
acciones
[ELSIF condicion THEN
acciones] ...
[ELSE
acciones]
END IF;- [ ]parte opcional
- ...se puede repetir
- condicion
Una expresión lógica, por ejemplo student_age < 18. Se ejecuta la primera rama cuya condición sea verdadera y las demás se omiten.
- acciones
Una o varias sentencias SQL, cada una terminada en ;. Se ejecutan si se elige esta rama.
- ELSIF
Otra rama con su propia condición. Solo se comprueba si todas las condiciones anteriores son falsas. Puede haber varias ramas así.
Palabra claveOpcional- ELSE
La rama que se ejecuta si ninguna condición ha resultado verdadera.
Palabra claveOpcional
Ejemplo de uso de IF
Vamos a crear un procedimiento que determina la categoría de un estudiante según su edad:
MySQL 8.4CREATE PROCEDURE categorize_student_by_age( IN student_id INT, OUT category VARCHAR(20) ) BEGIN DECLARE student_age INT; -- Obtenemos la edad del estudiante SELECT TIMESTAMPDIFF(YEAR, birthday, CURDATE()) INTO student_age FROM Student WHERE id = student_id; -- Determinamos la categoría según la edad IF student_age < 18 THEN SET category = 'Menor de edad'; ELSEIF student_age BETWEEN 18 AND 25 THEN SET category = 'Joven'; ELSE SET category = 'Adulto'; END IF; END; -- Uso del procedimiento CALL categorize_student_by_age(1, @category); SELECT @category AS age_category;
Vamos a crear una función que determina la categoría de un estudiante según su edad:
MySQL 8.4CREATE OR REPLACE FUNCTION categorize_student_by_age(student_id INT) RETURNS VARCHAR(20) LANGUAGE plpgsql AS $$ DECLARE student_age INT; category VARCHAR(20); BEGIN -- Obtenemos la edad del estudiante SELECT EXTRACT(YEAR FROM AGE(CURRENT_DATE, birthday)) INTO student_age FROM Student WHERE id = student_id; -- Determinamos la categoría según la edad IF student_age < 18 THEN category := 'Menor de edad'; ELSIF student_age BETWEEN 18 AND 25 THEN category := 'Joven'; ELSE category := 'Adulto'; END IF; RETURN category; END; $$; -- Uso de la función SELECT categorize_student_by_age(1) AS age_category;
La sentencia CASE
La sentencia CASE ofrece una forma más elegante de procesar varias condiciones.
Sintaxis de CASE
CASE
WHEN condicion THEN resultado
[WHEN ...]
[ELSE resultado_por_defecto]
END- [ ]parte opcional
- ...se puede repetir
- condicion
Una expresión lógica que se comprueba en su rama WHEN. Puede haber varias ramas: se ejecuta la primera cuya condición sea verdadera.
- resultado
El valor que toma CASE si la condición de esta rama es verdadera.
- resultado_por_defecto
El valor para el caso en que no se cumpla ninguna condición. Sin ELSE se devuelve NULL.
Opcional
CASE
WHEN condicion THEN resultado
[WHEN ...]
[ELSE resultado_por_defecto]
END- [ ]parte opcional
- ...se puede repetir
- condicion
Una expresión lógica que se comprueba en su rama WHEN. Puede haber varias ramas: se ejecuta la primera cuya condición sea verdadera.
- resultado
El valor que toma CASE si la condición de esta rama es verdadera.
- resultado_por_defecto
El valor para el caso en que no se cumpla ninguna condición. Sin ELSE se devuelve NULL.
Opcional
Ejemplo de uso de CASE
Vamos a crear el mismo procedimiento de clasificación de estudiantes, pero ahora con la sentencia CASE:
MySQL 8.4CREATE PROCEDURE categorize_student_with_case( IN student_id INT, OUT category VARCHAR(20) ) BEGIN DECLARE student_age INT; -- Obtenemos la edad del estudiante SELECT TIMESTAMPDIFF(YEAR, birthday, CURDATE()) INTO student_age FROM Student WHERE id = student_id; -- Determinamos la categoría con CASE SET category = CASE WHEN student_age < 18 THEN 'Menor de edad' WHEN student_age BETWEEN 18 AND 25 THEN 'Joven' ELSE 'Adulto' END; END; -- Uso del procedimiento CALL categorize_student_with_case(1, @category); SELECT @category AS age_category;
Vamos a crear la misma función de clasificación de estudiantes, pero ahora con la sentencia CASE:
MySQL 8.4CREATE OR REPLACE FUNCTION categorize_student_with_case(student_id INT) RETURNS VARCHAR(20) LANGUAGE plpgsql AS $$ DECLARE student_age INT; category VARCHAR(20); BEGIN -- Obtenemos la edad del estudiante SELECT EXTRACT(YEAR FROM AGE(CURRENT_DATE, birthday)) INTO student_age FROM Student WHERE id = student_id; -- Determinamos la categoría con CASE category := CASE WHEN student_age < 18 THEN 'Menor de edad' WHEN student_age BETWEEN 18 AND 25 THEN 'Joven' ELSE 'Adulto' END; RETURN category; END; $$; -- Uso de la función SELECT categorize_student_with_case(1) AS age_category;
El bucle WHILE
El bucle WHILE permite ejecutar código repetidamente mientras se cumpla una condición determinada.
Sintaxis de WHILE
WHILE condicion DO
acciones
END WHILE;- condicion
Una expresión lógica que se comprueba antes de cada pasada del bucle. Mientras sea verdadera, las acciones se repiten.
- acciones
Las sentencias SQL del cuerpo del bucle. Entre ellas debe haber algo que, tarde o temprano, haga falsa la condición; si no, el bucle no terminará nunca.
WHILE condicion LOOP
acciones
END LOOP;- condicion
Una expresión lógica que se comprueba antes de cada pasada del bucle. Mientras sea verdadera, las acciones se repiten.
- acciones
Las sentencias SQL del cuerpo del bucle. Entre ellas debe haber algo que, tarde o temprano, haga falsa la condición; si no, el bucle no terminará nunca.
Ejemplo de uso de WHILE
Veamos un ejemplo de procedimiento almacenado que crea varias asignaturas de prueba:
MySQL 8.4CREATE PROCEDURE create_test_subjects(IN count_subjects INT) BEGIN DECLARE i INT DEFAULT 1; DECLARE subject_id INT DEFAULT 20; WHILE i <= count_subjects DO INSERT INTO Subject (id, name) VALUES ( subject_id + i, CONCAT('Test Subject ', i) ); SET i = i + 1; END WHILE; END; -- Creamos 3 asignaturas de prueba CALL create_test_subjects(3); -- Comprobamos el resultado SELECT * FROM Subject WHERE name LIKE 'Test Subject%';
MySQL 8.4CREATE OR REPLACE PROCEDURE create_test_subjects(count_subjects INT) LANGUAGE plpgsql AS $$ DECLARE i INT := 1; subject_id INT := 20; BEGIN WHILE i <= count_subjects LOOP INSERT INTO Subject (id, name) VALUES ( subject_id + i, 'Test Subject ' || i ); i := i + 1; END LOOP; RAISE NOTICE 'Se han creado % asignaturas de prueba', count_subjects; END; $$; -- Creamos 3 asignaturas de prueba CALL create_test_subjects(3); -- Comprobamos el resultado SELECT * FROM Subject WHERE name LIKE 'Test Subject%';
¡Las estructuras de control de flujo convierten los procedimientos y funciones almacenados en una herramienta potente para implementar lógica de negocio compleja directamente en la base de datos! 🚀