Cursor MySQL: recorrer un conjunto de registros

Si usa mucho los procedimientos almacenados de MySQL, probablemente necesite recorrer un conjunto de registros para procesar un conjunto de datos. Esto se puede hacer a través de un Cursor MySQL.

Declaración de un cursor MySQL

Para declarar un cursor, debe utilizar la declaración DECLARE CURSOR con el SELECT que permite tener el conjunto de datos en la zona de declaración del procedimiento (por lo tanto, después de BEGIN y antes de HANDLERS).
Tomemos el ejemplo de un cursor que recorre todos los precios de una base de artículos:

 DECLARE monCurseur CURSOR FOR SELECT prix_ht, taux_tva, prix_ttc FROM article_tarif;

Recorriendo los resultados del cursor MySQL

Para hacer un bucle en los resultados de un cursor, deberá abrir el cursor y el bucle, asignar los campos de la línea a las variables, hacer el procesamiento que desee y, finalmente, cerrar el bucle y el cursor:

DECLARE var_prix_ht DECIMAL(18,2);
DECLARE var_taux_tva DECIMAL(18,2);
DECLARE var_prix_ttc DECIMAL(18,2);
...

OPEN monCurseur;
tarif_loop: LOOP
  FETCH monCurseur INTO var_prix_ht, var_taux_tva, var_prix_ttc;
  ...
END LOOP;
CLOSE monCurseur;

Una vez que FETCH alimenta sus variables, puede realizar los diversos procesos apropiados. Si alguna vez tiene valores nulos en sus variables después de un FETCH y no entiende por qué, puede consultar este artículo del sitio .

Establecer una condición de parada en el ciclo

Tal como está, con el código anterior obtendrá un error de tiempo de ejecución cuando pase por el cursor y llegue al final del conjunto de registros. Para evitar esto, y también para tener una condición de salida en el ciclo (y evitar un posible ciclo infinito), podrá definir un HANDLER dedicado.

DECLARE done INT DEFAULT 0;
...
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
...
/* dans la boucle */
IF done = 1 THEN
LEAVE tarif_loop;
END IF;

Otra forma de salir también, puede establecer sus variables en NULL al final del turno, y probar si una variable que no debería ser nula es nula en el ciclo, y hacer LEAVE en este momento

/* dans la boucle */
IF var_prix_ht IS NULL THEN
LEAVE tarif_loop;
END IF;
...
SET var_prix_ht = NULL;

En resumen, el código completo para nuestro ejemplo sería el siguiente:

DECLARE var_prix_ht DECIMAL(18,2);
DECLARE var_taux_tva DECIMAL(18,2);
DECLARE var_prix_ttc DECIMAL(18,2);
DECLARE done INT DEFAULT 0;
DECLARE monCurseur CURSOR FOR
SELECT prix_ht, taux_tva, prix_ttc FROM article_tarif;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN monCurseur;
tarif_loop: LOOP
FETCH monCurseur INTO var_prix_ht, var_taux_tva, var_prix_ttc;

IF done = 1 THEN
LEAVE tarif_loop;
END IF;

/* mettre ici le traitement à effectuer */

END LOOP;
CLOSE monCurseur;

Recursos

Documentos oficiales

Deja una respuesta