comparações entre tabelas e inserção

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
cleberzumba
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 223
Registrado em: Qui, 14 Dez 2006 10:45 am
Localização: Brasília-DF
Cleber Zumba de Souza

Pessoal, seguinte:

Tenho tres tabelas A, B e C. a tabela C tem uma quantidade de registros que contem na tabela A e B e preciso comparar se essas quantidades batem mesmo. Pensei em algo assim, mas acho que fica muito lento, alguém pode me ajudar a montar essa rotina de uma forma mais rápida??

Selecionar tudo

PROCEDURE CARGA_LANCAMENTO   IS


    CURSOR c_lancamento IS
    
        SELECT *
        FROM    A;
        
    CURSOR c_item IS
    
        SELECT *
        FROM    B;
        
    CURSOR c_controle IS
    
        SELECT P.qtde_documento qtd_doc, P.qtde_itens qtd_item
        FROM    C  P;

    v_cont_lanc   number := 0;
    v_cont_item   number := 0;
    
BEGIN
    for c_lancamento_rec in c_lancamento loop
    
       select count(*)
       into   v_cont_lanc
       from   A;

            for c_controle_rec in c_controle loop

                if c_controle_rec.qtd_doc <> v_cont_lanc then
                    --insere na tabela de erro
                else
                    insert into A;
                end if;

            end loop;

    end loop;

    for c_item_rec in c_item loop

        select count(*)
        into   v_cont_item
        from   B;

            for c_controle_rec in c_controle loop

                if c_controle_rec.qtd_item <> v_cont_item then
                    --insere na tabela de erro
                else
                    insert into B;
                end if;

            end loop;

    end loop;

EXCEPTION
     WHEN others THEN
          -- insert na tabela de log_erro
END; -- Procedure
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

Tem muita coisa na sua rotina que está mal...
Exemplo:

Selecionar tudo

for c_lancamento_rec in c_lancamento loop
   
       select count(*)
       into   v_cont_lanc
       from   A;

            for c_controle_rec in c_controle loop

                if c_controle_rec.qtd_doc <> v_cont_lanc then
                    --insere na tabela de erro
                else
                    insert into A;
                end if;

            end loop;

    end loop; 
1. pra todas linhas da tabela LANCAMENTO, você está fazendo um COUNT da tabela A. (se na lançamento tiver 1 milhão de linhas, você está fazendo um COUNT de A um milhão de vezes :-(
2. pra todas essas linhas, você também está abrindo um outro cursor :-(

Depois disso eu parei de olhar :-)

Veja, é muito mais simples você usar os recursor "naturais" do SQL. Deixa o banco fazer o serviço de comparação, não você!
Algo assim:

Tudo que está em A e que NÃO está em C, será mostrado...

Selecionar tudo

SELECT * 
FROM A
WHERE NOT EXISTS ( select 1 from C where  A.campochave = C.campochave)
Tudo que está em B e que NÃO está em C, será mostrado...

Selecionar tudo

SELECT * 
FROM B
WHERE NOT EXISTS ( select 1 from C where  B.campochave = C.campochave)
Daí você pega esse resultado e INSERE, loga, faz o que quiser... Pode até colocar num insert. (se a gente tivesse mais informações sobre suas tabelas, quais campos são chave, como eles se relacionam, daria pra dar uns exemplos menos "abstratos")

É possível também fazer um FULL OUTER JOIN pra ver o que existe e o que não existe entre duas tabelas.
http://glufke.net/oracle/viewtopic.php?t=206

Outra coisa que você pode estudar é o MERGE
http://glufke.net/oracle/viewtopic.php?t=305
:-o
cleberzumba
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 223
Registrado em: Qui, 14 Dez 2006 10:45 am
Localização: Brasília-DF
Cleber Zumba de Souza

Valeu cara, to mesmo enferrujado...tinha mais de uma ano que eu não programava, erro de iniciante esse, valeu mesmo....
cleberzumba
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 223
Registrado em: Qui, 14 Dez 2006 10:45 am
Localização: Brasília-DF
Cleber Zumba de Souza

Não dá para fazer da sua forma porque a tabela C contém somente duas colunas: qtde_total_A e qtde_total_B.

então tenho que fazer assim:

Selecionar tudo

select qtde_doc, qtde_item
into v_cont_doc, v_qtde_item
from C;

select count(*) 
into   v_cont_lanc 
from   A;

if v_cont_lanc <> v_qtde_doc then
   --condicao
else
   --consicao
end if;


select count(*) 
into   v_cont_item 
from   B;

if v_cont_item <> v_qtde_item then
   --condicao
else
   --consicao
end if;

eu pensei dessa forma, ou você teria uma outra mais rápida?...pois estou trabalhando com uma quantidade de dados muito grande, tudo na casa dos milhões.
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

É meio difícil dizer algo, pois não temos a estrutura das tabelas nem como elas se relacionam :-(
cleberzumba
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 223
Registrado em: Qui, 14 Dez 2006 10:45 am
Localização: Brasília-DF
Cleber Zumba de Souza

todas essas tres tabelas são tabelas temporarias, sem PK, sem FK, sem indices, elas são carregadas, depois eu vou tratando os dados desta forma e só depois irei inserir nas tabelas definitivas do modelo de dados.....e tudo tem q estar muito rapido. então sobre essas tres tabelas, elas são temporarias e não se relacionam.
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

Sim, tudo bem, mas a gente tem que entender a lógica que existe entre elas.
Tipo, a tabela A tem X,Y,Z campos.
a tabela B tem T,R,Z campos

o campo Z das duas tem que ser contado e fechar a quantidade...

etc...

senão não dá pra adivinhar
cleberzumba
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 223
Registrado em: Qui, 14 Dez 2006 10:45 am
Localização: Brasília-DF
Cleber Zumba de Souza

o projeto é novo, não existe nem base de dados ainda, eu é que baixei o oracle XE para ir bolando as procedures. Entrarei em contato quando tiver mais informações....
cleberzumba
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 223
Registrado em: Qui, 14 Dez 2006 10:45 am
Localização: Brasília-DF
Cleber Zumba de Souza

dr_gori...o que eu preciso fazer um pouco urgente é como fazer para carregar duas tabelas do oracle através do sqlloader. sei que em script shell eu farei isso, mas preciso saber fazer no shell as verificações necessárias, se os dados estão correto e em quais tabelas e campos eu devo carregar. complicado isso né?....é a parte mais complicada do projeto....pode me ajudar?
cleberzumba
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 223
Registrado em: Qui, 14 Dez 2006 10:45 am
Localização: Brasília-DF
Cleber Zumba de Souza

o que eu preciso fazer é o seguinte:

Eu tenho uma carga, através do SQL LOADER, de uma massa de dados(na casa dos milhoes) que deverá ser feita a partir de um arquivo de texto que possui um padrão de layout já definido.
Responder
  • Informação
  • Quem está online

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