Fórum Problemas com Triggers e procedures #418633
16/06/2012
0
Olá pessoal!
Tenho uma tabela de código de barras com o nome EAN que possui os seguintes campos (produto, codbarras, sequencia).
Criei uma procedure que ordena o número do campo da sequencia deixando sempre em ordem crescente (1,2,3,4,5,...).
Estou chamando essa procedure em um trigger que criei na tabela EAN, veja:
CREATE DEFINER = root@localhost TRIGGER `ean_after_del_tr` AFTER DELETE ON `ean`
FOR EACH ROW
BEGIN
CALL sp_ordenaean(OLD.produto);
END;
Quando vou fazer o teste, é apresentado a seguinte mensagem: Cant update table ean in stored function/trigger because it is already used by statament which invoked this stored function/trigger.
Mas quando excluo o trigger e faço o teste, sem usar o trigger, a procedure funciona perfeitamente.
Alguém poderia me dar uma ajuda?
Segue abaixo o código da procedure:
CREATE DEFINER = root@localhost PROCEDURE `sp_ordenaean`(
IN prod INTEGER(11)
)
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE cnt INT DEFAULT 1;
DECLARE barra char(15);
DECLARE eanprod CURSOR FOR (
select codbarras from ean
where produto = prod order by sequencia
);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN eanprod;
REPEAT
FETCH eanprod INTO barra;
if not done then
update ean set sequencia = cnt where produto = prod and codbarras = barra;
set cnt = cnt + 1;
end if;
UNTIL done END REPEAT;
CLOSE eanprod;
END;
Agradeço desde já qualquer ajuda.
Tenho uma tabela de código de barras com o nome EAN que possui os seguintes campos (produto, codbarras, sequencia).
Criei uma procedure que ordena o número do campo da sequencia deixando sempre em ordem crescente (1,2,3,4,5,...).
Estou chamando essa procedure em um trigger que criei na tabela EAN, veja:
CREATE DEFINER = root@localhost TRIGGER `ean_after_del_tr` AFTER DELETE ON `ean`
FOR EACH ROW
BEGIN
CALL sp_ordenaean(OLD.produto);
END;
Quando vou fazer o teste, é apresentado a seguinte mensagem: Cant update table ean in stored function/trigger because it is already used by statament which invoked this stored function/trigger.
Mas quando excluo o trigger e faço o teste, sem usar o trigger, a procedure funciona perfeitamente.
Alguém poderia me dar uma ajuda?
Segue abaixo o código da procedure:
CREATE DEFINER = root@localhost PROCEDURE `sp_ordenaean`(
IN prod INTEGER(11)
)
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE cnt INT DEFAULT 1;
DECLARE barra char(15);
DECLARE eanprod CURSOR FOR (
select codbarras from ean
where produto = prod order by sequencia
);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN eanprod;
REPEAT
FETCH eanprod INTO barra;
if not done then
update ean set sequencia = cnt where produto = prod and codbarras = barra;
set cnt = cnt + 1;
end if;
UNTIL done END REPEAT;
CLOSE eanprod;
END;
Agradeço desde já qualquer ajuda.
Vagner Almeida
Curtir tópico
+ 0
Responder
Posts
25/06/2012
Eduardo Gonçalves
Não sou especialista em MySQL, mas creio que esse é o famoso caso do mutating trigger, muito comum no Oracle. O que ocorre é que no trigger sobre a tabela ean você está chamando uma procedure que atualiza a própria tabela ean. Provavelmente, o MySQL não permite esse tipo de recurso.
O que você pode fazer para contornar? Algumas opções:
1- fazer sempre as suas atualizações usando uma procedure, nunca chamando insert ou update direto. Daí você pode remover o trigger e colocar todas as ações necessárias para a atualização no corpo dua sua procedure; ou
2- mudar o código do seu trigger, para que ele passe a fazer tudo que a procedure atualmente faz.
Att.,
Eduardo
O que você pode fazer para contornar? Algumas opções:
1- fazer sempre as suas atualizações usando uma procedure, nunca chamando insert ou update direto. Daí você pode remover o trigger e colocar todas as ações necessárias para a atualização no corpo dua sua procedure; ou
2- mudar o código do seu trigger, para que ele passe a fazer tudo que a procedure atualmente faz.
Att.,
Eduardo
Responder
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)