ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Copiar tabela de um Servidor SQL para outro [Resolvido]

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Qui Jul 23, 2020 6:24 pm    Assunto: Copiar tabela de um Servidor SQL para outro [Resolvido] Responder com Citação

Preciso importar uma tabela de um Servidor SQL Server para outro Servidor SQL Server.

Consegui fazer funcionar criando 2 conexões ADO diferentes e percorrendo a query de origem e inserindo na query de destino:

Código:
procedure Tfrmtransf.CopiaTabela(DataSetOrigem, DataSetDestino: TDataSet);
var
  Field: TField;
begin
  DataSetOrigem.Open;
  DataSetOrigem.First;

  DataSetDestino.Open;

  ProgressBar1.Max := DataSetOrigem.RecordCount;
  ProgressBar1.Position := 0;

  while not DataSetOrigem.Eof do
  begin
    Application.ProcessMessages;
    ProgressBar1.Position := ProgressBar1.Position + 1;

    DataSetDestino.Append;

    for Field in DataSetOrigem.Fields do
      DataSetDestino.Fields[Field.Index].Value := Field.Value;

    DataSetDestino.Post;

    DataSetOrigem.Next;
  end;

  ProgressBar1.Position := 0;
end;


Mas desta maneira fica muito lenta a importação.

Existe um script SQL para copiar dados entre tabelas de servidores diferentes?
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin


Editado pela última vez por natanbh1 em Sex Jul 24, 2020 11:18 am, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
joemil
Moderador
Moderador


Registrado: Quinta-Feira, 25 de Março de 2004
Mensagens: 9098
Localização: Sinop-MT

MensagemEnviada: Sex Jul 24, 2020 9:24 am    Assunto: Responder com Citação

ja tentou usar querys com CachedUpdates = true? assim vc pode enviar 100, 200, 300 registros de uma vez para o servidor de destino:

Código:
procedure Tfrmtransf.CopiaTabela(DataSetOrigem, DataSetDestino: TDataSet);
var
  Field: TField;
begin
  DataSetOrigem.Open;
  DataSetOrigem.First;

  QueryDestino.CachedUpdates := True;
  QueryDestino.sql.Text := 'SELECT * FROM tabela WHERE 1 = 0';
  QueryDestino.Open;

  ProgressBar1.Max := DataSetOrigem.RecordCount;
  ProgressBar1.Position := 0;

  while not DataSetOrigem.Eof do
  begin
    Application.ProcessMessages;
    ProgressBar1.Position := ProgressBar1.Position + 1;

    QueryDestino.Append;

    for Field in DataSetOrigem.Fields do
      DataSetDestino.Fields[Field.Index].Value := Field.Value;

    QueryDestino.Post;

    DataSetOrigem.Next;

    if (QueryDestino.RecordCount >= 200) or (DataSetOrigem.Eof) then
    begin
      QueryDestino.ApplyUpdates;
      QueryDestino.Close;
      QueryDestino.Open;
    end;
  end;

  ProgressBar1.Position := 0;
end;

_________________
<b>SEMPRE COLOQUE [RESOLVIDO] NO SEU POST</b>
Enviar imagens: http://tinypic.com/
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Sex Jul 24, 2020 10:40 am    Assunto: Responder com Citação

Obrigado pela sugestão Joelmil.

Estou usando componentes ADO e notei que a ADOQuery não tem as propriedades CachedUpdates e ApplyUpdates.

Tem a propriedade ChacheSize.

Há possibilidade de trabalhar em Cache com ADO?
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Sex Jul 24, 2020 11:09 am    Assunto: Responder com Citação

Dei uma pesquisada e consegui adaptar o código para o ADO.

Altere a propriedade CacheSize para a quantidade de registros que você quer armazenar em memória e o comando para atualizar no banco é o UpdateBatch.

É necessário alterar também a propriedade LockType para ltBatchOptimistic.

O código ficou assim:

Código:
procedure CopiaTabela(DataSetOrigem, DataSetDestino: TADOQuery; tabela: string);
var
  Field: TField;
begin
  DataSetOrigem.Open;
  DataSetOrigem.First;

  DataSetDestino.CacheSize := 1000;
  DataSetDestino.LockType := ltBatchOptimistic;
  DataSetDestino.SQL.Text := Concat('SELECT * FROM ', tabela, ' WHERE 1 = 0');
  DataSetDestino.Open;

  ProgressBar1.Max := DataSetOrigem.RecordCount;
  ProgressBar1.Position := 0;

  while not DataSetOrigem.Eof do
  begin
    Application.ProcessMessages;
    ProgressBar1.Position := ProgressBar1.Position + 1;

    DataSetDestino.Append;

    for Field in DataSetOrigem.Fields do
      DataSetDestino.Fields[Field.Index].Value := Field.Value;

    DataSetOrigem.Next;

    if (DataSetDestino.RecordCount >= 1000) or (DataSetOrigem.Eof) then
    begin
      DataSetDestino.Post;
      DataSetDestino.UpdateBatch();
      DataSetDestino.Close;
      DataSetDestino.Open;
    end;
  end;

  ProgressBar1.Position := 0;
end;


Uma importação de 2.400 registros que gastava 7 minutos e 30 segundos passou a ser feita em 1 e 30 segundos. Ótimo!

Se houver uma outra maneira mais eficiente ainda, eu aceito sugestões rsrs..

Muito obrigado Joemil.
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin


Editado pela última vez por natanbh1 em Seg Jul 27, 2020 10:44 am, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Sex Jul 24, 2020 11:24 am    Assunto: Responder com Citação

Bom dia,

natanbh1, não sei se você chegou a testar mas uma alternativa no SQL Server seria configurar um linked server.
Com essa ligação seria possível executar por exemplo um Insert / Select onde os dados não trafegariam pela aplicação, mas você também não conseguiria exibir para o usuário a evolução da execução do comando.
Não sei ao certo como vai ser a diferença no desempenho.

Espero que ajude


Editado pela última vez por imex em Qui Set 16, 2021 5:27 pm, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Sex Jul 24, 2020 11:45 am    Assunto: Responder com Citação

Bom dia Imex,

Nas minhas pesquisas anteriores, encontrei o link abaixo que indica essa opção do linked-server mas não explica como configurar:

Como transferir os dados de uma tabela para outra em servidores diferentes

Você sabe como configurar um linked-server no SQL Server?
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Sex Jul 24, 2020 12:18 pm    Assunto: Responder com Citação

Não lembro qual página segui na época, talvez tenha sido essa abaixo:
https://docs.microsoft.com/pt-br/sql/relational-databases/linked-servers/create-linked-servers-sql-server-database-engine?view=sql-server-ver15

Pelo que lembro não era um procedimento complexo, era algo simples de configurar.
Sobre esse tópico que você viu, acho que não é necessário utilizar a OpenQuery como foi sugerido lá, acho que pode ser algo semelhante ao que segue:

Código:
insert into TabelaDestino
    select * from [ServidorOrigem].[BancoOrigem].[dbo].[TabelaOrigem]


Espero que ajude
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
natanbh1
Colaborador
Colaborador


Registrado: Terça-Feira, 15 de Março de 2011
Mensagens: 3093
Localização: Belo Horizonte - MG

MensagemEnviada: Seg Jul 27, 2020 10:41 am    Assunto: Responder com Citação

Vou tentar implementar e analisar a performance.

Muito obrigado Imex.
_________________
''A persistência é o caminho para o êxito.''
Charlie Chaplin
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Enviar E-mail
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB