Jump to content
Diego Farias

Erro: Trigger que executa um INSERT e depois UPDATE no mesmo bloco PL/SQL

Recommended Posts

Diego Farias

Boa tarde pessoal,

Tenho uma trigger para não permitir a atualização se o preço for negativo e registrar na tabela valor_produto. A trigger é dispara na tabela produto.

Segue o código para entender melhor :

CREATE TABLE PRODUTO (
CODIGO NUMBER(4),
VALOR NUMBER(7,2));
INSERT INTO produto VALUES (1001, 2.55);
INSERT INTO produto VALUES (1002, 3.25);
INSERT INTO produto VALUES (1003, 2.85);
-- Criar outra tabela denominada VALOR_PRODUTO:
CREATE TABLE VALOR_PRODUTO (
CODIGO NUMBER(4),
VALOR_ANTERIOR NUMBER(7,2),
VALOR_NOVO NUMBER(7,2));
CREATE OR REPLACE TRIGGER VERIFICA_VALOR
BEFORE UPDATE OF VALOR ON PRODUTO
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
WHEN( NEW.VALOR < 0 )
BEGIN
 INSERT INTO VALOR_PRODUTO
 VALUES(:OLD.CODIGO, :OLD.VALOR, :NEW.VALOR);
 UPDATE PRODUTO
 SET VALOR = :OLD.VALOR
 WHERE CODIGO = :NEW.CODIGO;
END VERIFICA_VALOR;
/
UPDATE PRODUTO SET VALOR = -701.03 WHERE CODIGO = 1003;
SELECT * FROM PRODUTO;
SELECT * FROM VALOR_PRODUTO;

O erro acontece quando o update é executado:

Erro a partir da linha : 84 no comando -

UPDATE PRODUTO SET VALOR = -701.03 WHERE CODIGO = 1003

Relatório de erros -

Erro de SQL: ORA-04091: a tabela SYSTEM.PRODUTO é mutante; talvez o gatilho/função não possa localizá-la

ORA-06512: em "SYSTEM.VALORPRODUTO_BEFORE_UPDATE", line 4

ORA-04088: erro durante a execução do gatilho 'SYSTEM.VALORPRODUTO_BEFORE_UPDATE'

ORA-06512: em "SYSTEM.PRODUTO_BEFORE_UPDATE", line 9

ORA-04088: erro durante a execução do gatilho 'SYSTEM.PRODUTO_BEFORE_UPDATE'

04091. 00000 - "table %s.%s is mutating, trigger/function may not see it"

*Cause: A trigger (or a user defined plsql function that is referenced in

this statement) attempted to look at (or modify) a table that was

in the middle of being modified by the statement which fired it.

*Action: Rewrite the trigger (or function) so it does not read that table.

Também tentei criar duas triggers, que quando a tabela produto for atualizada com valor negativo, ela dispara a trigger1 e inseri dados na tabela valor_produto, que dispara a trigger2 assim que o INSERT é feito e faz um update na tabela produto para voltar ao valor original, mas não deu certo.

Segue código:

CREATE OR REPLACE TRIGGER produto_before_update
BEFORE UPDATE
ON PRODUTO
FOR EACH ROW
DECLARE
v_username varchar2(10);
BEGIN
IF :NEW.VALOR < 0 THEN
 -- Find username of person performing UPDATE on the table
 SELECT user INTO v_username FROM dual;
 INSERT INTO VALOR_PRODUTO
 VALUES(:OLD.CODIGO, :OLD.VALOR, :NEW.VALOR, v_username, sysdate);	
 END IF;
END;
/
CREATE OR REPLACE TRIGGER valorProduto_before_update
AFTER INSERT
ON VALOR_PRODUTO
FOR EACH ROW
BEGIN
 IF :NEW.VALOR_NOVO < 0 THEN
 UPDATE PRODUTO
 SET VALOR = OLD.VALOR_ANTERIOR
 WHERE CODIGO = :NEW.CODIGO;	
END IF;
END;
/
SELECT * FROM PRODUTO;
UPDATE PRODUTO SET VALOR = -701.03 WHERE CODIGO = 1003;
SELECT * FROM VALOR_PRODUTO;
SELECT * FROM PRODUTO;

Li nesse fórum http://www.techonthenet.com/oracle/errors/ora04091.php que isso e um erro da oracle, mas não estou sabendo resolver alguém pode ajudar. ?

Obrigado

Edited by Diego Farias

Share this post


Link to post
Share on other sites
PaisNeto

Bom dia,

Repara numa coisa, tu estás a fazer um update a um registo e nesse update dizes para fazer outro update, antes do primeiro ser feito...

Que é o que te diz o link que tens aí

"When you create a trigger against a table, you can't modify/query that table until the trigger/function has completed."

Tu fazes o update à tabela a partir de onde, forms, apex?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.