[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
  

Mensagemem Qui, 15 Set 2005 11:39 am

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:
Código: Selecionar todos
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).

Código: Selecionar todos
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_MES_EMBARQUE = a.NU_MES_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
dr_gori
Localização: Portland, OR USA

Thomas F. G

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

Mensagemem Ter, 15 Ago 2006 4:24 pm

Gracias pela ajuda, Dr Gori. :)
suelana
Localização: Joinville-SC

Suelana BLU-JLLE


  • Veja também
    Respostas
    ExibiÇões
    Última mensagem