Uma pergunta relativamente simples, mas de todas as minhas pesquisas, não consegui encontrar uma resposta decente.
O que é tecnicamente mais correto, abrir o cursor depois que os manipuladores forem definidos ou antes de realmente usar o cursor?
Por exemplo,
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE a CHAR(16);
DECLARE b, c INT;
DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur1;
OPEN cur2;
read_loop: LOOP
FETCH cur1 INTO a, b;
FETCH cur2 INTO c;
IF done THEN
LEAVE read_loop;
END IF;
IF b < c THEN
INSERT INTO test.t3 VALUES (a,b);
ELSE
INSERT INTO test.t3 VALUES (a,c);
END IF;
END LOOP;
CLOSE cur1;
CLOSE cur2;
END;
As declarações acima parecem ser padrão na maioria dos exemplos, no entanto, seria possível fazer
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE a CHAR(16);
DECLARE b, c INT;
DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
SELECT x,y,z INTO @X, @Y, @Z FROM TableA WHERE X=1;
IF (@X >= @Y) THEN
OPEN cur1;
OPEN cur2;
read_loop: LOOP
FETCH cur1 INTO a, b;
FETCH cur2 INTO c;
IF done THEN
LEAVE read_loop;
END IF;
IF b < c THEN
INSERT INTO test.t3 VALUES (a,b);
ELSE
INSERT INTO test.t3 VALUES (a,c);
END IF;
END LOOP;
CLOSE cur1;
CLOSE cur2;
ELSE
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO a, b;
IF done THEN
LEAVE read_loop;
END IF;
INSERT INTO test.t3 VALUES (a,b);
END LOOP;
CLOSE cur1;
END IF;
END;
Eu posso ver o que seu segundo código está fazendo. Você deseja abrir 2 cursores apenas se certas condições forem atendidas, mas apenas 1 cursor se não forem atendidas. IMHO que deve estar bem.
Na verdade, o livro MySQL Stored Procedure Programming tem este código de amostra nas páginas 110-111 no Exemplo 5-17
Observe no código a abertura e o fechamento de um cursor dentro de um
BEGIN...END
bloco. Você deve estar bem com seu código. Se o mysql reclamar, coloque seu código THEN e ELSE dentro deBEGIN...END
blocos.