Tuesday 19 May 2009

Usando PL/SQL para ler uma tabela e atualizar outra

Ola pessoal, a algum tempo que ja nao posto nada aqui, mas e por varios motivos, o principal e minha mudanca para a Australia.
Mas vamos la, semana passada eu passei por uma migracao de dados pegando um arquivo .xls do Excel e transformando ele para .csv, que e um arquivo delimitado por virgulas, para entao usando o SQL Loader do Oracle importar esses campos para uma tabela Oracle e entao ler esta, comparando os dados com outra e atualizando esta e se os dados nao batessem, ou seja nao existissem nessa tabela, salvar em uma outra tabela. Claro que nesse site nao e possivel colocar todas as indentacoes.
Aqui esta um exemplo, que e muito util, e usando Oracle Cursor, pois procurei muito isso na net e so consegui achar em livros especificos.

O codigo :

set serveroutput on
declare
v_voipFlag varchar2(20);
v_xtype number(1);
v_serviceType varchar2(100);
v_serviceTypeId number(22);
v_de varchar2(20);
v_para varchar2(20);
v_data_de_aceitacao date;
v_cliente_Id number(22);
v_area_Id number(22);
v_achado number(10);
v_conta number(10);
cursor updateapp is
select migra_tabela.VOIP_FLAG, migra_tabela.service_type, migra_tabela.de_NUM, migra_tabela.TO_NUM,
migra_tabela.acceptance_date, migra_tabela.numb_client_id, migra_tabela.area_type_id
de migra_tabela
order by migra_tabela.de_NUM;
begin
dbms_output.enable;
open updateapp;
loop
fetch updateapp into v_voipFlag, v_serviceType ,v_de, v_para, v_data_de_aceitacao, v_cliente_Id, v_area_Id;

v_achado := 0;
v_voipFlag := upper(trim(v_voipFlag));

if (v_voipFlag <> 'NAO') or
(v_voipFlag <> 'SIM') then v_xtype := 9;
end if;

if (v_voipFlag = 'NAO') then v_xtype := 0;
end if;
if (v_voipFlag = 'SIM') then v_xtype := 1;
end if;

-- Look for one value
select count(low_number) into v_achado de aplicacao
where (v_de = aplicacao.LOW_NUMBER
and v_para = aplicacao.HIGH_NUMBER
and v_data_de_aceitacao = to_char(aplicacao.ACCEPTANCE_DATE,'DD-Mon-YY')
and aplicacao.APPLICATION_STATE_ID = 6);

-- Look for one value
dbms_output.put_line('v_achado' || v_achado);

if (v_achado < de_num =" v_de" to_num =" v_para" numb_client_id =" v_cliente_Id" area_type_id =" v_area_Idand" acceptance_date =" v_data_de_aceitacao);" voip_flag =" v_xtype" v_de =" aplicacao.LOW_NUMBER" v_para =" aplicacao.HIGH_NUMBER" v_data_de_aceitacao =" to_char(aplicacao.ACCEPTANCE_DATE,'DD-Mon-YY')"> 9);
commit;
exit when updateapp%NOTFOUND;
end loop;
close updateapp;
end;


O codigo e um pouco grande, mas ele percorre toda a tabela de migra_tabela comparando com da aplicacao, se achar na aplicacao ele atualiza, se nao achar ele procura na tabela nao_bate, se achar algum registro que satisfaca as condicoes ele atualiza senao ele cria um novo.
E simple porem muito poderoso.
Eu usei um muito parecido para uma migracao de dados em producao, e rodaram com perfeicao, claro que eram outros dados e outras condicoes, mas o esqueleto esta ai, e so copiar dar uma estudada no codigo e maos a obra.
So mais uma coisa... prestem bem atencao pois como nesse blog nao foi possivel colocar o sinal correto. Para se atribuir um valor voce usa := (dois pontos e igual sem espacos no meio).

1 comment:

Unknown said...

Boa meu velho amigo, proximo projeto que eu pegar de JSF vou usar o 2.0