NJM 0 Denunciar post Postado Agosto 19, 2010 Olá a todos, sou iniciante em oracle. Estou usando como linguagem o Delphi. Estou tentando colocar todas as regras gerenciais dentro do banco e me deparei com um problema. Acontece que tenho uma tabela pai (produto) e uma tabela filho (lote_produto), fiz uma trigger que dispara após deletar uma linha da tabela lote_produto, ele verifica se existe mais alguma linha daquele produto na lote_produto, caso não exista deve apagar a linha da tabela produto (pai), acontece que quando vou verificar se existe mais linhas da lote_produto ele dá erro de "mutanting", se coloca o "Pragma Autonomous_Transaction" ele até passa mas quando vai apagar a linha da produto dá erro de "deadlock", criei uma view para fazer este select e continuou com o erro de mutating, criei uma procedure para fazer o delete e continuou com o deadlock, não quero levar esta rotina para dentro do programa pois quero ter certeza da integridade dos dados. Alguem teria alguma sugestão para resolver este problema? Obrigado, segue o codigo : create or replace trigger TG_TESTE after delete on lote_produto for each row declare V_QTDE NUMBER(10,2); Pragma Autonomous_Transaction; begin begin SELECT COUNT(1) INTO V_QTDE FROM LOTE_PRODUTO WHERE PRODUTO_LOTE_ID = :OLD.PRODUTO_LOTE_ID; EXCEPTION WHEN NO_DATA_FOUND THEN V_QTDE := 0; END; IF V_QTDE =0 THEN DELETE FROM PRODUTO WHERE PRODUTO_LOTE_ID = :OLD.PRODUTO_LOTE_ID; END IF; end TG_TESTE; Compartilhar este post Link para o post Compartilhar em outros sites
Motta 645 Denunciar post Postado Agosto 19, 2010 Não tem um modo simples de evitar a "tabela mutante". Tente fazer o seguinte : faça a trigger de statement ao invés de for each row. A trigger de statement é executada após o fim da instrução, por ser de instrução não existem as variáveis new/old. Verifique nesta trigger se existe registro "pai" sem "filho" e aí faça a deleção, esta verificação deve ser para toda a tabela e não apenas para o que foi deletado. Esta trigger pode tornar a transação lenta, pois um delete de uma linha fará uma leitura na tabela toda. Solução possível, criar uma procedura que faz esta limpeza é chamá-la pela aplicação. -- Veja também : Qual a opção de ON DELETE da tabela "pai" em relação à "filho" pois se está com ON DELETE CASCADE a delação da trigger faz a deleção em cascata que chama a trigger de forma recursiva, uma solução e usar ON DELETE SET NULL ou RESTRICT. Para mais detalhes. Espero ter ajudado. Compartilhar este post Link para o post Compartilhar em outros sites