[Dica] Insert de registros entre 2 bancos.

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
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

Veja que situação interessante:
Tive que copiar +ou- 800 mil registros da base QUENTE para uma base de testes. Ótimo! Criei o DB_LINK entre as duas base e mandei ver o script de INSERT - que comitava de 1000 em 1000.

De cara, deu erro de FK violada, ou seja, essa tabela se relaciona com outras e essas outras NÃO ESTAVAM populadas como na base quente. Em resumo: além do INSERT dos 800 mil, eu tinha que fazer INSERT de cada tabela relacionada.

Para isso, criei uma PROCEDURE que gera o INSERT (eu informando a FK que deu erro).
Veremos:

Selecionar tudo

create or replace procedure thomas (con varchar2) is
  ban  varchar2(100):='@quente';  --> nome do DB LINK
  --
  cons varchar2(100);
  tab  varchar2(100);
  i    number;
  tmp  varchar2(100);
begin
  --busac nome da Constraint relacionada
  select r_constraint_name
  into cons
  from user_constraints
  where constraint_name=CON;
  
  --Busca o nome da tabela relacionada
  SELECT TABLE_NAME
  INTO TAB
  FROM USER_CONSTRAINTS
  WHERE CONSTRAINT_NAME = cons;
  
  --gera o INSERT !
  dbms_output.put_line('----------------------------------------------------');
  dbms_output.put_line('insert into '||tab||' (');
  dbms_output.put_line('SELECT * FROM '||tab||ban||' a');
  dbms_output.put_line('WHERE not exists');
  dbms_output.put_line('  (SELECT * FROM '||tab||' b');

  --para cada campo da PK faz o relacionamento.
  i:=0;  
  for vcur
  in (select *
      from user_cons_columns a
      where a.constraint_name=cons
     )
  loop
    i:=i+1;
    if i=1 
    then tmp:='    where ';
    else tmp:='      and ';
    end if;
    dbms_output.put_line( tmp ||'b.'||vcur.column_name ||' = a.'||vcur.column_name);
    
  end loop;

  --fim  
  dbms_output.put_line(' ));');
  dbms_output.put_line('---------------------------------------------------- ');  
end;
/

Ou seja, cada vez que dava erro de FK, eu fazia o seguinte: Colocava a procedure pra rodar com o NOME da FK. A procedure, retorna o INSERT entre os 2 bancos, inserindo apenas o que falta! (um tipo de synchronize).

Selecionar tudo

SQL> exec thomas('CE_EMBARQUE6');
----------------------------------------------------
insert into TB_LOTE_EMBARQUE (
SELECT * FROM TB_LOTE_EMBARQUE@quente a
WHERE not exists
  (SELECT * FROM TB_LOTE_EMBARQUE b
    where b.CD_SEGURADO = a.CD_SEGURADO
      and b.NU_mês_EMBARQUE = a.NU_mês_EMBARQUE
      and b.NU_ANO_EMBARQUE = a.NU_ANO_EMBARQUE
      and b.CD_LOTE = a.CD_LOTE
 ));
----------------------------------------------------

PL/SQL procedure successfully completed.

SQL> 
Ou seja, basta executar o INSERT gerado e comitar. Se nesse insert der um erro de FK novamente, basta rodar a procedure informando essa nova FK que deu erro. SHow de bola!

:-o
suelana
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 63
Registrado em: Qui, 10 Ago 2006 6:07 pm
Localização: Joinville-SC
Suelana BLU-JLLE

Gracias pela ajuda, Dr Gori. :)
Responder
  • Informação
  • Quem está online

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