Trigger não executa, acusa tabela mutante.

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
pyro
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 323
Registrado em: Qui, 21 Set 2006 10:21 am
Localização: Barala - TT

Tenho uma tabela que ao inserir dados ela precisa disparar uma trigger para coletar os dados dela e de outra tabela (ambas estão relacionadas por uma ID) e inserir em outra tabela, quando eu tento fazer isso a trigger acusa que a tabela é mutante e dá erro. Alguém pode dar uma força?
Olha o código da minha trigger:
Código:

Selecionar tudo

create or replace trigger insert_tabela_c
  after insert on tabela_b 
  for each row
declare
  data         date;
  peso         number(10,4);
  precisao     varchar(1);
  maquina      number(6);
  produto      number(5);
begin
  select cod_aca, cod_maquina
         into produto,
              maquina
  from tabela_a
  where amo_codigo = :new.amo_codigo;
 
  select ame.ame_data, ame.ame_peso, ame.ame_precisao
         into data,
              peso,
              precisao
  from tabela_b ame
  where amo_codigo = :new.amo_codigo;

  insert into tabela_c(data_med, peso, precisao, cod_maquina, cod_aca)
         values(data, peso, precisao, maquina, produto);
         
end insert_tabela_c;
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

O problema é que você está fazendo select na TABELA_B, e a trigger é da própria TABELA_B. Isso o Oracle não permite.

Pra contornar, existe uma série de formas.
Veja essas:
http://glufke.net/oracle/viewtopic.php?t=96
http://glufke.net/oracle/viewtopic.php?t=1009
:-o
pyro
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 323
Registrado em: Qui, 21 Set 2006 10:21 am
Localização: Barala - TT

Já vi esse tópico, até utilizei as dicas contidas lá, mas passou acusar que os dados não existem.

Desculpe minha ignorância, mas você sabe uma maneira correta de pegar os dados da tabela que disparou a trigger para inseri-los em outra tabela?
pyro
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 323
Registrado em: Qui, 21 Set 2006 10:21 am
Localização: Barala - TT

Esse problema desse tópico eu consegui resolver, valeu pela força.
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Pyro, beleza brother?

Caso a resolução não tenha sido uma daques soluções apresentadas nos links, pelo Gori, por favor poste como resolveu, para que os demais possam ter como referência caso necessitem.

Grato,
pyro
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 323
Registrado em: Qui, 21 Set 2006 10:21 am
Localização: Barala - TT

Bem aqui está como ficou a trigger final e funcionando:

Selecionar tudo

create or replace trigger insert_medicoes
  after insert on amostragem_medicao  
  for each row
declare
  maquina      number(6);
  produto      number(5);
begin
  select cod_aca, cod_maquina 
         into produto, 
              maquina
  from amostragem
  where amo_codigo = :new.amo_codigo;

  insert into medicoes2(data_med, peso, precisao, cod_maquina, cod_aca)
         values(:new.ame_data, :new.ame_peso, :new.ame_precisao, maquina, produto);     
end insert_medicoes;
chrisinteract
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Ter, 17 Jul 2007 11:02 am
Localização: Lajeado - RS

E ai!!!!!
Estou me aventurando por esse mundo do Oracle e isso ta trazendo uma dor de cabeça enorme pois estou querendo montar um trigger de uma tabela que alimenta uma segunda com apenas dois campos e não estou conseguindo...exemplo:
Tenho as tabelas TT e XX.
Os campos da tabela TT são: ref_user int e dt_login date, isso quando for inserido um registro nessa tabela preciso q a trigger dispare jogando as informações na segunda XX q tem os seguintes campos: dd date e tt int;
Como sou marinheiro de primeira viagem gostaria muito de um auxilio da galera...

Abraço
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Bom dia,

Você poderia estar utilizando o :NEW.campo_desejado para inserir na segunta tabela, assim que inserir na primeira.

Procure por trigger neste fórum, que irá achar uns exemplos interessantes, como este

qualquer dúvida, manda ai.
chrisinteract
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Ter, 17 Jul 2007 11:02 am
Localização: Lajeado - RS

Obrigado pelas dicas Travisolli...!!!
Mas estou quebrando a cabeça para numa coisa q acredito que é muito facil mas realmente não estou conseguindo andar nisso...de uma olhada e vê se consegue me ajudar:

create or replace trigger tr_tt
after insert or update on tt
for each row
declare
ref_user int;
dt_login date;
begin
select ref_user, dt_login
into = tt, xx
from tt
where ref_user = new_user , dt_login = new_login
go

Abraço
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Faz o seguinte, tenta adaptar este exemplo.
Tabelas: EMP + T_LOG (Criada abaixo)

Selecionar tudo


CREATE TABLE T_LOG (SEQ    NUMBER(04),
                    EMPNO  NUMBER(04),
                    DT_ATU DATE,				    TP_ATU VARCHAR2(01));
						  
Em seguida, segue a Trigger que é disparada sempre que insiro ou atualizo a emp:

Selecionar tudo

CREATE OR REPLACE TRIGGER TR_INSERE_LOG
 BEFORE 
 INSERT OR UPDATE
 ON EMP
 REFERENCING OLD AS OLD NEW AS NEW
 FOR EACH ROW 
DECLARE
V_SEQ    NUMBER(04) := 0;
V_TP_ATU VARCHAR2(01);
BEGIN

  IF INSERTING
  THEN
    V_TP_ATU := 'I';
  ELSIF UPDATING
  THEN
    V_TP_ATU := 'U';
  END IF;

  SELECT MAX(SEQ)+1 --- AQUI PODERIA SER UMA SEQUENCE TB.
    INTO V_SEQ
    FROM T_LOG;

  INSERT INTO T_LOG
       VALUES (V_SEQ,
		         :NEW.EMPNO,
					SYSDATE,
					V_TP_ATU);
EXCEPTION
 WHEN OTHERS THEN
   RAISE_APPLICATION_ERROR(-20001, 'Erro ao popular tabela de log (T_LOG) : ' || SQLERRM);
END;

Espero ter ajudado.
chrisinteract
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Ter, 17 Jul 2007 11:02 am
Localização: Lajeado - RS

Mais uma vez obrigado Trevisolli, ajudou sim e exclareceu...

Valeu
chrisinteract
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Ter, 17 Jul 2007 11:02 am
Localização: Lajeado - RS

Ai pessoal!!!
Está me acusando erro nessas sintaxes:

Selecionar tudo

declare
        ref_user varchar(25);
        dt_login varchar(12);        

begin
    select count(*),count(*) 
        into ref_user,dt_login
            from TT;
    declare
        tt varchar(25);
        dd varchar(12);
    
    begin
        insert into XX
            values (ref_use,:new.tt,dt_logins,:new.dd); 
    end;         
end;
Será q alguém pode me ajudar????

Abraço
chrisinteract
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Ter, 17 Jul 2007 11:02 am
Localização: Lajeado - RS

Faltou o erro...

>[Error] Script lines: 1-17 -------------------------
ORA-01008: not all variables bound

Abraço
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Brother,

No VALUES, não seria DT_LOGIN, e não DT_LOGINS?
Karlinhoz
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 1
Registrado em: Seg, 25 Fev 2013 11:23 am

Amigos preciso de ajuda também..... Estou começando com o oracle agora e não consigo resolver este problema abaixo, por favor me ajudem:

Selecionar tudo

CREATE OR REPLACE TRIGGER TBU_ENCERRAPROGNOSTICO
BEFORE UPDATE OF arquivado1, arquivado2, arquivado3
ON SAPC.PROCESSO
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW

DECLARE

vlnPROG NUMBER;

BEGIN

 SELECT NVL(COUNT(cod_interno),0)
    INTO vlnPROG
    FROM SAPC.PROCESSO
   WHERE (cod_interno = :NEW.cod_interno)
     AND PROB_EXITO In (1,2);
     
IF(vlnPROG > 0) THEN

      IF(:OLD.arquivado1||:OLD.arquivado2||:OLD.arquivado3 <> 'N' AND :NEW.arquivado1||:NEW.arquivado2||:NEW.arquivado3 = 'S') THEN
      RAISE_APPLICATION_ERROR(-20003,'Não é permitido o encerramento de processo com prognóstico PROVÁVEL ou POSSÍVEL');
      END IF;

END IF;

END;

Mesmo erro de tabela mutante.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 11 visitantes