Comparar registros entre dois bancos de dados diferentes

27/01/2016

5

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

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários. Para saber mais sobre o uso de cookies,
consulte nossa política de privacidade. Ao continuar navegando em nosso site, você concorda com a nossa política.

Aceitar