Comparar registros entre dois bancos de dados diferentes
27/01/2016
0
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)?
Gabriel
Post mais votado
27/01/2016
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
Ruy Salles
Mais Posts
28/01/2016
Gabriel
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
28/01/2016
Raimundo Pereira
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 ?
28/01/2016
Ruy Salles
A sua rotina funcionou corretamente?
29/01/2016
Gabriel
Ainda não tentei usar o método locate, é uma boa dica (ainda não conhecia), vou tentar agora
29/01/2016
Gabriel
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!
29/01/2016
Raimundo Pereira
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
29/01/2016
Gabriel
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
29/01/2016
Raimundo Pereira
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.
29/01/2016
Raimundo Pereira
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);
29/01/2016
Gabriel
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.
29/01/2016
Gabriel
Agora funcionou.
Muito grato pela paciência
Clique aqui para fazer login e interagir na Comunidade :)