Je souhaite faire quelque chose qui semble un peu compliqué dans MySQL. En fait, je souhaite ouvrir un curseur, faire une boucle, et dans cette boucle, ouvrir un deuxième curseur en utilisant les données de l'extraction précédente pour être exécuté, et re-boucle sur les résultats.
DECLARE idind INT;
DECLARE idcrit INT;
DECLARE idindid INT;
DECLARE done INT DEFAULT 0;
DECLARE done2 INT DEFAULT 0;
DECLARE curIndicateur CURSOR FOR SELECT id_indicateur FROM indicateur;
DECLARE curCritereIndicateur CURSOR FOR SELECT C.id_critere FROM critere C where C.id_indicateur=idind;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
set idindid=54;
OPEN curIndicateur;
REPEAT
FETCH curIndicateur INTO idind;
open curCritereIndicateur;
REPEAT
FETCH curIndicateur INTO idcrit;
INSERT INTO SLA_DEMANDE_STATUS (iddemande,idindicateur,indicateur_status,progression) values('0009',idcrit,'OK',10.0);
UNTIL done END REPEAT;
close curCritereIndicateur;
UNTIL done END REPEAT;
CLOSE curIndicateur;
En fait, comment faire "Until done" différemment pour les deux curseurs, car vous ne pouvez déclarer qu'un seul gestionnaire pour SQLSTATE? Si le premier se termine, le second se termine également.
Vous devez définir un nouveau BLOC dans votre première boucle de curseur et utiliser différentes déclarations dans ce bloc.
Quelque chose comme:
BLOCK1: begin
declare v_col1 int;
declare no_more_rows boolean1 := FALSE;
declare cursor1 cursor for
select col1
from MyTable;
declare continue handler for not found
set no_more_rows1 := TRUE;
open cursor1;
LOOP1: loop
fetch cursor1
into v_col1;
if no_more_rows1 then
close cursor1;
leave LOOP1;
end if;
BLOCK2: begin
declare v_col2 int;
declare no_more_rows2 boolean := FALSE;
declare cursor2 cursor for
select col2
from MyOtherTable
where ref_id = v_col1;
declare continue handler for not found
set no_more_rows2 := TRUE;
open cursor2;
LOOP2: loop
fetch cursor2
into v_col2;
if no_more_rows then
close cursor2;
leave LOOP2;
end if;
end loop LOOP2;
end BLOCK2;
end loop LOOP1;
end BLOCK1;
Ou redéfinissez le CONTINUER POIGNEE:
//...
LOOP1: LOOP
fetch cursor1
into v_col1;
if no_more_rows1 then
close cursor1;
leave LOOP1;
end if;
//...
SET no_more_rows1=false;//That's new
END LOOP LOOP1;
Il semble que toutes les instructions select dans une boucle exécutent la commande CONTINUE HANDLE.
DECLARE _idp INT;
DECLARE _cant INT;
DECLARE _rec INT;
DECLARE done INT DEFAULT 0;
-- Definición de la consulta
DECLARE primera CURSOR FOR SELECT dp.id_prod, SUM(dp.cantidad) AS cantidad, pp.receta FROM tm_detalle_pedido AS dp INNER JOIN tm_producto_pres AS pp
DECLARE segunda CURSOR FOR SELECT id_ins, cant FROM tm_producto_ingr WHERE id_pres = _idp;
-- Declaración de un manejador de error tipo NOT FOUND
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
-- Abrimos el primer cursor
OPEN primera;
REPEAT
FETCH primera INTO _idp, _cant, _rec;
IF NOT done THEN
OPEN segunda;
block2: BEGIN
DECLARE doneLangLat INT DEFAULT 0;
DECLARE _ii INT;
DECLARE i FLOAT;
DECLARE _canti FLOAT;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET doneLangLat = 1;
REPEAT
FETCH segunda INTO _ii,_canti;
IF NOT doneLangLat THEN
IF _rec = 1 THEN
SET i = _canti * _cant;
-- Insertamos
INSERT INTO tm_inventario (id_ins,id_tipo_ope,id_cv,cant,fecha_r)
VALUES (_ii, 2, @id, i, _fecha);
END IF;
END IF;
UNTIL doneLangLat END REPEAT;
END block2;
CLOSE segunda;
END IF;
UNTIL done END REPEAT;
CLOSE primera;
vous pouvez utiliser loop et redéfinir la valeur du handle, comme ceci:
get_something:loop
open cur;
fetch cur into temp_key;
if no_more_record=1 then
set no_more_record=0;
close cur;
leave get_something;
else
//do your job;
end if;
end loop;
Corrigez-moi si je me trompe, mais il semblerait que vous essayiez de créer une insertion en bloc d'enregistrements dans votre table "SLA_DEMANDE_STATUS". Incluez tous les critères pour chaque indicateur trouvé et attribuez-lui par défaut les valeurs «0009», «OK» et 10,0 pour chaque identifiant de critère.
Tout cela peut être fait en une seule insertion SQL. INSERT INTO ... à partir d'un SQL-Select ...
Maintenant, si vous souhaitez inclure uniquement une seule entrée "id_indicateur", vous pouvez l'ajouter à la clause WHERE de l'instruction select.
Notez que mon SQL-Select a forcé les valeurs à correspondre aux colonnes que vous voulez avoir renseignées. Ils seront tous insérés dans la table de destination du même nom. La bonne chose à ce sujet, vous pouvez simplement exécuter la partie SQL-SELECT uniquement pour voir les données que vous vous attendriez à avoir insérées ... si elles sont incorrectes, vous pouvez les ajuster pour respecter toutes les restrictions que vous souhaitez.
insert into SLA_DEMANDE_STATUS
( iddemande,
idindicateur,
indicateur_status,
progression )
SELECT
'0009' iddemande,
c.id_criterere idindicateur,
'OK' indicateur_status,
10.0 progression
FROM
indicateur i;
JOIN critere c
ON i.id_indicateur = c.id_indicateur