Comparar registros entre dois bancos de dados diferentes

27/01/2016

4

Boa tarde,

em uma aplicação que estou desenvolvendo tenho em um DataModule, dois TSQLConnection (No caso ZConnection porque estou usando o componente ZeosDBO), cada um conectando em um banco diferente. Para cada conexão, eu tenho uma querry acessando a mesma tabela de cada banco (os bancos são idênticos em estrutura de tabelas).

Então eu fiz o código, para que cada registro que ele achar no outro banco que for igual ao registro verificado, ele mostre a mensagem "Achei!"

Segue o código:
procedure TForm1.btnCompararClick(Sender: TObject);
var
  cont: integer; //contador para informar a quantidade de resgistros verificados
  achouid: string; //variável para informar o número de id buscado;
begin

     dmzeos.ZQuery1.SQL.Clear;
     dmzeos.ZQuery2.SQL.Clear;
     dmzeos.ZQuery1.SQL.Add('Select * from contacts');
     dmzeos.ZQuery2.SQL.Add('Select * from contacts');
     dmzeos.ZConnection1.Connected:=true;
     dmzeos.ZConnection2.Connected:=true;
     dmzeos.ZQuery1.Active:=true;
     dmzeos.ZQuery2.Active:=true;
     dmzeos.ZQuery1.First;
      cont:=1;
        while not dmzeos.ZQuery1.EOF do
         begin
          while not dmzeos.ZQuery2.EOF do
           begin
             if (dmzeos.ZQuery1.FieldByName('first_name').text = dmzeos.ZQuery2.FieldByName('first_name').Text)then
               begin
                  achouid:= dmzeos.ZQuery2.FieldByName('id').Text;
                  application.MessageBox(Pchar('achei! Foram verificados '+ inttostr(cont)+ ' registros, '+(achouid)+ ' é o número de id') ,'olá',0);
                  dmzeos.ZQuery1.Next; //caso ache o registro ele pula para o próximo a ser encontrado
                  dmzeos.ZQuery2.First; //volto para o inicio da tabela para nova verificação
                  cont:=1; //Volto para 1 o contador
               end;
           dmzeos.ZQuery2.next;
           cont:= cont + 1;
          end;
        end;

end;                                                                     



Quando executo o código, ele trava, mas eu só fiz alterações para acessar dois bancos diferentes, sendo que antes ele acessava o mesmo banco apenas em tabelas diferentes (e funcionava).

Alguém sabe se por ele estar acessando dois bancos diferentes ele trava? Ou é algo na lógica? A quantidade de dados influencia na execução (o banco 1 tem ~8 mil registros e o segundo ~100 mil)?
Responder

Post mais votado

27/01/2016

Tente isso GbsManolo

while not dmzeos.ZQuery1.EOF do
begin //1
while not dmzeos.ZQuery2.EOF do
begin //2
if (dmzeos.ZQuery1.FieldByName('first_name').text = dmzeos.ZQuery2.FieldByName('first_name').Text)then
begin //3
achouid:= dmzeos.ZQuery2.FieldByName('id').Text;
application.MessageBox(Pchar('achei! Foram verificados '+ inttostr(cont)+ ' registros, '+(achouid)+ ' é o número de id') ,'olá',0);
dmzeos.ZQuery1.Next; //caso ache o registro ele pula para o próximo a ser encontrado
dmzeos.ZQuery2.First; //volto para o inicio da tabela para nova verificação
cont:=1; //Volto para 1 o contador
Application.ProcessMessages // -----> acrescente esta linha
end; //1
end //2
dmzeos.ZQuery2.next;
cont:= cont + 1;
end;//3

Espero ter ajudado
Responder

Mais Posts

28/01/2016

Gabriel

Ruy,

Para que serve esta linha?

onde vc colocou não deu certo, mas depois da linha ZQuery2.Next; parece que a aplicação volta a responder
Responder

28/01/2016

P2

gabsmanolo, Boa tarde.

Por que não realizar um for e lacate com varios campos ?
A ideia não verificar a existência dos dados no banco de dados secundário ?
Responder

28/01/2016

Ruy Salles

Ele libera a memória do computador por milisegundos.

A sua rotina funcionou corretamente?
Responder

29/01/2016

Gabriel

Ainda não funcionou, não sei se é pelas limitações de minha máquina

Ainda não tentei usar o método locate, é uma boa dica (ainda não conhecia), vou tentar agora
Responder

29/01/2016

Gabriel

Agora funcionou, o código ficou assim:

while not dmzeos.ZQuery1.EOF do
        begin
               achouid:= dmzeos.ZQuery1.FieldByName('CNPJ').text;
               if( dmzeos.zquery2.Locate('id', achouid,[loCaseInsensitive, loPartialKey])) then
                begin
                application.MessageBox(Pchar('Achei!' + achouid),'Olá',0);
                end
               else
               begin
                application.MessageBox('Não Achei!','Olá',0);
               end;
         dmzeos.ZQuery1.next;
        end;


Achei que ficou bem mais otimizado, mas não usei o for pq tenho dúvida se precisaria de um contador para verificar até o ultimo registro (sou newbie)

Obrigado pela ajuda!
Responder

29/01/2016

P2

Pode tentar assim:

Para ficar melhor :

1. Gaug
1. Memo_encontrados.
1. Memo_nao_encontrados.


dmzeos.ZQuery1.SQL.Clear;
dmzeos.ZQuery2.SQL.Clear;
dmzeos.ZQuery1.SQL.Add('Select * from contacts');
dmzeos.ZQuery2.SQL.Add('Select * from contacts');
dmzeos.ZConnection1.Connected:=true;
dmzeos.ZConnection2.Connected:=true;
dmzeos.ZQuery1.Active:=true;

gaug.max:= dmzeos.ZQuery1.recordcount;
gaug.progress:=0;

Memo_encontradaos.lines.clear;
Memo_nao_encontradaos.lines.clear;

dmzeos.ZQuery1.First;

dmzeos.ZQuery2.Active:=true;


if not dmzeos.ZQuery1.EOF then
repeat
gaug.sufix:=' % + Processando ['+dmzeos.ZQuery1.FieldByName('CNPJ').asstring+']';
if( dmzeos.zquery2.Locate('id', dmzeos.ZQuery1.FieldByName('CNPJ').asstring,[loCaseInsensitive, loPartialKey])) then
begin
memo_encontrados.lines.add('dmzeos.ZQuery1.FieldByName('CNPJ').asstring');
end
else
begin
memo_nao_encontrados.lines.add('dmzeos.ZQuery1.FieldByName('CNPJ').asstring');
end;
dmzeos.ZQuery1.next;
gaug.progress:=gaug.progress+1;

Application.ProcessMessages;

end;

until dmzeos.ZQuery1.EOF;
application.MessageBox(Pchar(memo_encontrados),'Relação de registros localizados',0);
application.MessageBox(Pchar(memo_nao_encontrados),'Relação de registros não localizados',0);

Dá até pra fazer um relatório...

O repeat faz a função do contador, ou seja enquanto não for o ultimo registro da tabela ele vai realizar a verificação e seguir para o próximo registro.

Com isso primeiro será processado todos os registros no final receberá duas mensagens.
Dá uma enxugada nos comandos.

Espero que melhore sua rotina.
vlw
Responder

29/01/2016

Gabriel

Tenho mais dúvidas

avançando no projeto, quero fazer com que ele verifique o campo do telefone, então fiz o código:
 while not dmzeos.ZQuery1.EOF do
        begin
               dmzeos.ZQuery2.Edit;
               dmzeos.ZQuery1.edit;
               achouid:= dmzeos.ZQuery1.FieldByName('CNPJ').text;
               if( dmzeos.zquery2.Locate('id', achouid,[loCaseInsensitive, loPartialKey])) then
                begin
                  if(dmzeos.ZQuery2.FieldByName('phone_office').text = 'null') or  (dmzeos.ZQuery2.FieldByName('phone_office').text = '') then
                   begin

                   dmzeos.ZQuery2.FieldByName('phone_office').text:= dmzeos.ZQuery1.FieldByName('phone_office').text;
                   dmzeos.ZQuery2.ApplyUpdates;
                   end;
                cont:=cont+1;
                end
               else
               begin
                cont2:=cont2 + 1;
               end;
         dmzeos.ZQuery1.next;
        end;
        application.MessageBox(Pchar('Foram encontrados '+ inttostr(cont)+ ' registros e '+ inttostr(cont2) +' não estão no banco'), 'Resultado', 1);


Quando eu executo, aparece a mensagem "Opperation not allowed, dataset '%s' is not in edit or insert state". No entanto como podem ver eu adicionei a linha ZQuery2.Edit; O que pode ser?

Sobre seu código, p2. Gaug, Memo_encontrados e Memo_não_encontrados são variáveis, certo? Como devo declara-las?

Perdão a quantidade de perguntas, mas é que realmente estou com bastante dificuldade e pesquisei bastante essa questão do edit e não consegui resolver
Responder

29/01/2016

P2

Memo_encontrados e Memo_nao_encontrados, são componentes >> Tmemo encontrasse na aba Standard
Coloque dois renomeio para Memo_encontrados e Memo_nao_encontrados


Gaug são componentes >> Tgauge encontrasse na aba Samples.
Coloque um e renomeio para Gaug.
Responder

29/01/2016

P2

while not dmzeos.ZQuery1.EOF do
begin
// dmzeos.ZQuery2.Edit; // Edição somente no momento da edição antes de atualizar então vou comentar
// dmzeos.ZQuery1.edit;//
achouid:= dmzeos.ZQuery1.FieldByName('CNPJ').text;

if( dmzeos.zquery2.Locate('id', achouid,[loCaseInsensitive, loPartialKey])) then //Tentou localizar
begin
if(dmzeos.ZQuery2.FieldByName('phone_office').text = 'null') or (dmzeos.ZQuery2.FieldByName('phone_office').text = '') then //Verifica o telefone
begin
dmzeos.ZQuery2.Edit; // Aqui entra em edição
dmzeos.ZQuery2.FieldByName('phone_office').text:= dmzeos.ZQuery1.FieldByName('phone_office').text;
dmzeos.ZQuery2.ApplyUpdates;
end;
cont:=cont+1;
end
else
begin
cont2:=cont2 + 1;
end;
dmzeos.ZQuery1.next;
end;
application.MessageBox(Pchar('Foram encontrados '+ inttostr(cont)+ ' registros e '+ inttostr(cont2) +' não estão no banco'), 'Resultado', 1);
Responder

29/01/2016

Gabriel

P2,

eu uso o Lazarus, não sei se por isso não tem essas abas. O tmemo eu acho em um componente que eu instalei e o tgauge não achei.
Responder

29/01/2016

Gabriel

coloquei o edit ali também, mas não havia funcionado, acho que pq coloquei os dois, enfim

Agora funcionou.


Muito grato pela paciência
Responder
×
+1 DevUP
Acesso diário, +1 DevUP
Parabéns, você está investindo na sua carreira