Trigger - Sincronizar dados de duas tabelas

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
lamanita
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 42
Registrado em: Seg, 17 Mai 2004 2:41 pm
Localização: Porto Alegre - RS
Samuel, o lamanit@

Olá pessoal

Tenho duas tabelas A e B que tem colunas semelhantes. Quando eu altero um campo em uma, tb altero o campo correspondente em outra. E vice-versa. O ideal era fazer esse controle por trigger, mas entrou em loop, pois quando altero na A, dispara a trigger para alterar na B, quando altera na B dispara a trigger para alterar na A.
Alguém já passou por essa situação ?
Obrigado.
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

Essas tabelas são no mesmo esquema?

Eu já fiz isso com tabelas em esquemas diferentes. Daí eu colocava bem no início do código assim:

No Esquema BRASIL:

Selecionar tudo

IF user='BRASIL'  
THEN
  código...  atualiza tabelas no esquema EUA
  código...
END IF;
e no Esquema EUA:

Selecionar tudo

IF user='EUA'  
THEN
  código...  atualiza tabelas no esquema BRASIL
  código...
END IF;
Dessa forma, a trigger seria rodada apenas uma vez!
lamanita
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 42
Registrado em: Seg, 17 Mai 2004 2:41 pm
Localização: Porto Alegre - RS
Samuel, o lamanit@

Sim, estão no mesmo...

Poderia me explicar melhor como tu faz com o esquema diferente, de repente eu possa dar um jeito de pedir pra trocarem o esquema.

Tu pega o onwer da tabela ou o usuário de banco ?
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

Eu tinha 2 sistemas rodando no mesmo servidor. (cada sistema, com um owner diferente)

O controle de usuários era a nível de sistema, ou seja, todos usuários se logavam com o mesmo usuário no banco e o sistema controlava.

Com isso, era possível fazer integrações de algumas tabelas: Tudo que era alterado num owner, era também alterado numa tabela equivalente no outro owner - para fins de integração dos sistemas.

Como era feito?
Ele testava na trigger quem era o USER que estava fazendo a alteração!
Já que cada sistema só alterava as suas próprias tabelas, a trigger testava se o USER fazendo a alteração era o mesmo. Se não fosse, isso significava que era fruto de um "LOOP" e parava por aí...
lamanita
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 42
Registrado em: Seg, 17 Mai 2004 2:41 pm
Localização: Porto Alegre - RS
Samuel, o lamanit@

Aqui os usuários do sistema são user do banco tb...
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

Então você pode fazer assim:

* Crie uma package que guarda uma variável. Já que essa variável é visível durante a sessão, você pode definir ali se é pra inserir.
Quando estiver inserindo na primeira, MUDE o valor, pois quando a trigger da outra for chamada, ela não vai inserir.

Pra exemplificar, eis o código:

Criando as tabelas

Selecionar tudo

create table x(id number,col1 varchar2(10))
/
create table y(id number,col1 varchar2(10))
/
Criando o pacote

Selecionar tudo

create or replace package test_pkg is
update_from_trigger boolean := false;
end;
/
Criando as triggers

Selecionar tudo

create or replace trigger x_bir_bur_bdr_trg
before insert or update or delete on x
for each row
begin

  if test_pkg.update_from_trigger = false then
     test_pkg.update_from_trigger := true;

     if inserting then
        insert into y (id,col1)
        values (:new.id,:new.col1);
     elsif updating then
           update y set col1 = :new.col1
           where id = :new.id;
     elsif deleting then
           delete from y
           where id = :old.id;
     end if;
  end if;

  test_pkg.update_from_trigger := false;
end;
/

create or replace trigger y_bir_bur_bdr_trg
before insert or update or delete on y
for each row
begin
 
  if test_pkg.update_from_trigger = false then
     test_pkg.update_from_trigger := true;

     if inserting then
        insert into x (id,col1)
        values (:new.id,:new.col1);
     elsif updating then
           update x set col1 = :new.col1
           where id = :new.id;
     elsif deleting then
           delete from x
           where id = :old.id;
     end if;
  end if;
  test_pkg.update_from_trigger := false;

end;
/
Testando!

Selecionar tudo

SQL> insert into x values (1,'a');

1 row created.

SQL> select * from y;

        ID COL1
---------- ----------
         1 a

SQL> insert into y values (2,'b');

1 row created.

SQL> 
SQL> select * from x;

        ID COL1
---------- ----------
         1 a
         2 b

SQL> 
Responder
  • Informação