[Delphi] Tabela temporária com ClientDataSet – Prática

[Delphi] Tabela temporária com ClientDataSet - PráticaOlá, leitores! Esse artigo é a continuação do tema sobre tabelas temporárias com ClientDataSet no Delphi. No artigo anterior, apresentei o conceito, vantagens e um exemplo de cenário no qual uma tabela temporária pode ser utilizada para evitar inconsistências. Após a teoria, finalmente vamos partir para a prática! Criaremos uma tabela temporária utilizando o mesmo exemplo de cenário mencionado no primeiro artigo!

 

Recapitulando o artigo anterior, lembre-se que temos a seguinte tabela de itens da venda:

-- Tabela ITENS
COD_VENDA (chave estrangeira referenciando a tabela VENDAS)
COD_PRODUTO
QTDE
VALOR
TOTAL

Nosso objetivo será criar uma tabela temporária para armazenar os itens da venda em memória, e somente quando o usuário clicar pra gravar a venda é que estes itens serão, de fato, inseridos no banco de dados.

Para criar uma tabela temporária, vamos utilizar o componente TClientDataSet, disponível na paleta Data Access do Delphi. Adicione-o no formulário, altere o nome para cdsTemporario e dê dois cliques para abrir o Fields Editor (Editor de Campos). Essa janelinha é onde definiremos os campos da tabela temporária.
Para adicionar um novo campo, clique com o botão direito dentro dessa janelinha e selecione a opção New Field.

Adicionar campo ao ClientDataSet

Uma nova janela será aberta para preencher as propriedades do campo que será adicionado.
No nosso caso, adicionaremos 4 campos:

Código do Produto:
Name: COD_PRODUTO
Type: Integer
Field Type: Data

Quantidade:
Name: QTDE
Type: Integer
FieldType: Data

Valor do Produto:
Name: VALOR
Type: Float
FieldType: Data

Total (quantidade multiplicada pelo valor):
Name: TOTAL
Type: Float
FieldType: Data

Campos adicionados no ClientDataSet


Por quê não adicionamos a descrição do produto?
Caro leitor, se você já trabalhou com master/detail alguma vez ou tem noções de normalização de dados, sabe que não devemos gravar a descrição do produto na tabela de itens da venda, já que temos o código do produto como chave estrangeira. Se adicionarmos a descrição do produto, teremos valores duplicados no banco de dados (na tabela Produtos e na tabela Itens da Venda), e isso é desnecessário. Apenas com o código do produto podemos facilmente buscar a descrição através de um relacionamento entre tabelas (inner join).

Quando terminar de adicionar os itens, feche o Fields Editor. Em seguida, clique com o botão direito no cdsTemporario e selecione a opção Create DataSet.

CreateDataSet para criar a tabela temporária

Pronto! A partir de agora já temos uma tabela temporária criada! A seguir, veja que a manipulação de dados também é bem simples.

Para inserir um registro na tabela temporária, utilizaremos o método Append para colocá-la em modo de inserção e o método Post para gravar o registro, tal como se estivéssemos trabalhando com uma tabela física. Considerando que temos componentes TEdit para cada campo da tabela temporária, o código de inserção ficaria da seguinte forma:

var
  Total: real;
begin
  cdsTemporario.Append;
  cdsTemporario.FieldByName('COD_PRODUTO').AsInteger := StrToInt(edtCodigo.Text);
  cdsTemporario.FieldByName('QTDE').AsInteger := StrToInt(edtQtde.Text);
  cdsTemporario.FieldByName('VALOR').AsFloat := StrToFloat(edtValor.Text);
  Total := StrToInt(edtQtde.Text) * StrToFloat(edtValor.Text);
  cdsTemporario.FieldByName('TOTAL').AsFloat := Total;
  cdsTemporario.Post;
end;

 

Observe que não há segredo algum! Para visualizar as inserções, adicione um componente TDBGrid e um TDataSource no formulário e faça as ligações entre os três componentes para exibir os dados.
Caso seja necessário alterar um registro da tabela temporária, basta utilizar o método Edit para colocar a tabela em modo de edição (alteração), ao invés do Append. Ah, e lembre-se de utilizar o Post para gravar as alterações. Por fim, se for necessário deletar um registro da tabela temporária, utilize o método Delete:

cdsTemporario.Delete;


Ok! Agora sei criar uma tabela temporária e manipular os dados, mas como devo proceder para gravar estes registros no banco de dados?

Muito simples! Mas antes disso, precisamos obter o código da venda para que seja possível gravar os itens da venda, concorda? Na verdade, isso depende de qual banco de dados você usa e como você definiu a tabela. Se o código da venda for um campo autoincremento, ele pode ser obtido através de uma função de retorno (como o RETURNING do Firebird ou @@IDENTITY do SQL Server). Por outro lado, se o código da venda é preenchido pelo sistema, podemos utilizar a função MAX em uma SQL, que retorna o valor máximo de um campo em uma tabela. No nosso caso, seria o campo Código da venda recém inserida:

var
  CodigoVenda: integer; // variável para armazenar o código da venda
begin
  // limpa a instrução SQL
  Query1.SQL.Clear; 
  // adiciona uma instrução SQL com a função MAX
  Query1.SQL.Add('Select MAX(COD_VENDA) as CodigoVenda from VENDAS');
  // abre a Query
  Query1.Open;
  // obtém o código da venda
  CodigoVenda := Query1.FieldByName('CodigoVenda').AsInteger;
  // fecha a Query
  Query1.Close;
end;

 

Pois bem, considere que temos outro ClientDataSet (chamado cdsItensVenda) que representa a tabela física de itens da venda no banco de dados. Para “copiar” os dados da tabela temporária para a tabela física, basta realizar um laço de repetição (loop) e gravar os itens, um a um. Complementando o código-fonte acima, nossa sintaxe finalmente ficará da forma abaixo. Para facilitar a visualização, quebrei algumas linhas do código, ok?

var
  CodigoVenda: integer;
begin
  { aqui estaria o código de gravação da venda }
 
  Query1.SQL.Clear;
  Query1.SQL.Add('Select MAX(COD_VENDA) as CodigoVenda from VENDAS');
  Query1.SQL.Open;
  CodigoVenda := Query1.FieldByName('CodigoVenda').AsInteger;
  Query1.Close;
 
  cdsTemporario.First; // move para o primeiro registro da tabela temporária
  while not (cdsTemporario.EOF) do // laço de repetição
  begin
    cdsItensVenda.Append; // coloca a tabela física em modo de inserção
 
    // copia os valores da tabela temporária para a tabela física
    cdsItensVenda.FieldByName('COD_VENDA').AsInteger :=
      CodigoVenda;
 
    cdsItensVenda.FieldByName('COD_PRODUTO').AsInteger :=
      cdsTemporario.FieldByName('COD_PRODUTO').AsInteger;
 
    cdsItensVenda.FieldByName('QTDE').AsInteger :=
      cdsTemporario.FieldByName('QTDE').AsInteger;
 
    cdsItensVenda.FieldByName('VALOR').AsInteger :=
      cdsTemporario.FieldByName('VALOR').AsInteger;
 
    cdsItensVenda.FieldByName('TOTAL').AsInteger :=
      cdsTemporario.FieldByName('TOTAL').AsInteger;
 
    cdsItensVenda.Post; // grava o item da venda
    cdsItensVenda.ApplyUpdates(0); // persiste a gravação no banco de dados
 
     // deleta o registro da tabela temporária
     // isso fará com que o próximo registro seja lido
    cdsTemporario.Delete;
  end;
end;

 

Em poucas linhas gravamos a venda e todos os itens dela em um mesmo método!
É bem mais rápido e seguro, não é?
Clique aqui e baixe um exemplo de tabela temporária com ClientDataSet desenvolvido em Delphi 7.  Neste exemplo, procurei incrementar mais algumas funções (como o recurso de Aggregates), e adicionei um campo “Descrição” para aprimorar a compreensão de tipos de dados no ClientDataSet. Analise o código e teste o exemplo. Caso houver dúvidas, não hesite em entrar em contato!

Antes que eu me esqueça, tabelas temporárias não servem exclusivamente para o cenário apresentado acima. Você pode utilizar tabelas temporárias para várias finalidades em diversas situações. O importante é compreender o conceito e saber aplicá-lo quando necessário.

 

Por hoje é só, leitores! Grande abraço!


Confira os outros artigos:

Tabela temporária com ClientDataSet – Conceito
Tabela temporária com ClientDataSet – Prática
Tabela temporária com ClientDataSet – Final


 

Compartilhe!
Share on FacebookTweet about this on TwitterShare on LinkedInShare on Google+Pin on PinterestEmail this to someone

54 comentários

  1. Vale lembrar que você também pode fazer com que o TClientDataSet trabalhe automaticamente com o banco de dados ligando TQuery > TDataSetProvider > TClientDataSet > TDataSource. Vale um artigo sobre isso, André?

  2. Interessante o artigo… Como estou iniciando no em programação Delphi já trabalhei desta forma de gravar e depois sair alterando .. kkk .Parabéns André.

    1. Basicamente sim, Frederico. Você ainda pode utilizar outros métodos para manipular os dados, como Delete (exclusão), Locate (localização), Filter (filtro), Refresh (atualização), além dos comandos Append, Edit e Post já mencionados.

  3. Realmente usar estas tabelas é fantástico, porém estou esbarrando num problema. Estou alimentando uma tabela dessas com mais de 5.000 registros (vindos de outra tabela).
    Um dos campos desta tabela é criado manualmente, trata-se de um campo tipo BOOLEAN que o usuário vai usar para marcar registros específicos e fazer algo com eles.
    Só que a alimentação desses 5 mil registros nesta tabela temporária está DEMORANDO DEMAIS. Existe uma forma de alimentar mais rapidamente essas tabelas temporárias?

    1. Olá, Ismael! Depende de qual forma você está alimentando os dados na tabela temporária. Talvez você pode “clonar” os dados, e isso leva bem menos tempo. De qualquer forma, vou entrar em contato com você por e-mail!

  4. André, estou com um problema em uma DBGrid que está ligada a um data source que por sua vez está ligado à um ClientDataSet, queria saber se você saberia como limitar a quantidade de caracteres de uma célula de uma DBGrid, por exemplo no campo Código da DBGrid só 2 caracteres, no campo Quantidade somente 6, e por assim vai..

    1. Olá, Eduardo. O limite de caracteres deve estar definido no ClientDataSet, e não na DBGrid. Por exemplo, se você criou um campo no ClientDataSet do tipo string de 20 caracteres, então o DBGrid irá automaticamente respeitar esse limite e não permitirá que mais de 20 caracteres sejam digitados na célula. Ok?

  5. André, por exemplo tenho um SQLConnection , um SQLDataSet, um DataSetProvider, um ClientDataSet e um Datasource, que está ligado a um banco de dados, então o que está exposto no DBGrid vem do banco, mas quando vai adicionar no DBGrid no campo Quantidade, ele não limita os caracteres e se for digitado além do permitido ele da um erro no Banco de Dados..

    1. Boa questão, Eduardo. No caso de campos do tipo string, a DBGrid obedece a limite de caracteres que foi definida paro o campo. Já para campos do tipo inteiro (como a Quantidade, no seu caso), eu recomendo que você crie uma máscara em tempo de execução para limitar a entrada do usuário, como por exemplo:
      ClientDataSet1.FieldBYName('Quantidade').EditMask := '000';

  6. gostaria de saber como eu faço para que o clientDatSet fique no estado True, porque toda vez que abro o delphi tenho que alterar essa opção..grato abraço….

    1. Olá, getulio. A princípio, só pelo fato de você ajustar a propriedade Active como True em tempo de projeto já seria o suficiente para mater o ClientDataSet sempre ativo, mesmo reiniciando o Delphi.

  7. André meu compatriota,Parabéns pelo seu trabalho e em compatilhar seu conhecimento!Sou estudante de S.I e estou começando à aprender Delphi.Queria se possível sua ajuda:
    Estou desenvolvendo um aplicativo pequeno de estoque e estou quebrando a cabeça
    com a tabela produto e venda. Queria uma ajuda sua meu guru Delphiano! No formulário “venda”, ao inserir o código do produto que é da tabela produto,
    mostrasse o nome do produto, a quantidade em estoque. Dái quando inserir no campo de “qtde” da tabela venda e gravasse a venda, desse baixa automática
    na tabela produto.
    RESUMINDO, QUERO FAZER UMA VENDA QUE DESSE BAIXA AUTOMÁTICA DO PRODUTO EM ESTOQUE
    Estou usando a paleta “Interbase” do Delphi 7 + Firebird 2.5

  8. Olá, André!
    Agradeço aos ‘deuses’ da Informática, por encontrá-lo falando de Delphi, e explicando muito bem sobre o assunto, neste momento que tanto preciso.
    Doutor, minha situação é de certa forma semelhante a do nosso companheiro Walter. Preciso desenvolver um aplicativo, onde no formulario eu escolhesse a categoria e partir daí incluisse os itens referentes a mesma, mas sem ter que ficar escolhendo toda vez a categoria antes de incluir os itens nela. Se é que me entende. Se puder entrar em contato comigo, poderei te explicar melhor. Desde já, agradeço!

  9. André, quanta qualidade em uma explicaçao, são poucos que sabem ensinar tao facilmente assim.
    Meu problema é assim: estou fazendo uma tela de venda(saida de produtos), estou usando delphi 7 + firebird 2.1, com os componentes da palheta interbase, gero uma nova venda, preencho os dados da venda, e os itens estou colocando em um DBGrid, como faço pra colocar essa tabela temporaria pra trabalhar com o DBgrid, facilitaria minha vida, nao quero colocar Edit’s para inserir itens, quero fazer isso direto em um DBgrid ou um componente com a mesma funçao.. Abraço Desde ja Agradeço!

    1. Olá, Thiago! Obrigado pelo comentário e pelo feedback! Thiago, podemos trabalhar com tabelas temporárias em DBGrids sem problema algum! A única diferença é que os dados estarão em memória, ao invés de armazenados no banco de dados. Isso é muito útil para trabalhar com vários registros que dependem de uma chave estrangeira que ainda não foi gravada.

  10. Cara
    Eu não costumo fazer isso, mas OBRIGADO
    Do fundo do meu coração, OBRIGADO

    Tu não tem idéia de como vc me ajudou com esse post

    Valeu ae 😀

  11. André, boa tarde!

    Excelente artigo! Me ajudará bastante numa rotina que estou desenvolvendo.
    Felicidades e sucesso para você!

    Muito obrigado.

  12. Bom dia, voce teria alguma dica de como colar colunas de excel no dbgrid delphi7,

    10 registro, e cada 1 ira representa um na tabela paradox,

    ou seje ficaria 10 registro em paradox.

    Grato.

  13. Há anos aprendendo com o mestre Batera, haha! Estou quase formado e ainda aprendo com você. Ainda irei trabalhar com você um dia. Ta muito bem explicado, e ajuda muito quem usa tabelas temporarias.

    corohsnk do forum ActiveDelphi.

    Abraço
    Att, João Alexandre.

    1. Fala, João Alexandre!
      Obrigado pelo comentário! Quem sabe um dia nos encontramos por aí, rsrs!
      Se tudo der certo, logo estarei de volta no ActiveDelphi. Abraço!

  14. Boa tarde, primeiramente gostaria de parabenizá-lo pelo excelente artigo me ajudou muito no meu problema fiz todo passo a passo. Funcionou beleza por uma exceção, o momento de mostrar no DBgrid. A minha implementação carrego os dados no DBgrid no click do botão. Acredito eu que os dados são carregados haja vista que ao inserir novos dados e clicar no botão novamente uma nova linha no DBGrid é Gerada, apenas não consigo visualizar no DBGrid. Desde já muito obrigado!

    1. Boa noite, Júnior! Se os dados não estão sendo exibidos na DBGrid, talvez ela não está conectada na tabela temporária (ClientDataSet). Verifique a propriedade DataSource da DBGrid, bem como a propriedade DataSet do DataSource. Abraço!

  15. Estou Com Um Problema ao Implementar seu Exemplo. ele funciona direitinho, Porém não consigo carregar os Dados no DBGrid.

    Atenciosamente.
    Júnior Lira

  16. Amigo, sou iniciante em programacao e estou com sérias dificuldades. Gostaria de saber se voce poderia passar um email e se eu poderia enviar uma dúvida pra voce.

    meu email é masters.jc@hotmail.com

    Desde já agradeco

    Joao

    1. Olá, josewillamis. Sim, as tabelas temporárias podem ser utilizadas como se fossem um DataSet conectado a uma tabela do banco de dados. Portanto, basta ligar a tabela temporária em um DataSource, e este DataSource em um DBNavigator!
      Abraço!

  17. André, boa tarde.

    Parabéns pelo trabalho!!!
    Tenho uma duvida, preciso alimentar MemDataSet, porém quando faço receber a informação da seguinte mensagem: “Field value required”. Eu preciso alterar somente um campo de varios que tenho.

    Estou fazendo dessa forma:

    DM.cdsCotacao.Edit; DM.mdsCotacao.FieldByName(‘PrecoFinal’).AsFloat := DM.mdsCotacao.FieldByName(‘Preco’).AsFloat;
    DM.cdsCotacao.Post;

    Como devo fazer nesse caso?

    1. Boa tarde, Lucas. Ao que parece, você está editando um DataSet e atribuindo o valor em outro, o que talvez possa estar causando o erro. De qualquer forma, vou entrar em contato por e-mail. Abraço!

  18. Caro André. Muito boa sua explanação! Só tenho uma dúvida, no trecho :
    // deleta o registro da tabela temporária
    // isso fará com que o próximo registro seja lido
    cdsTemporario.Delete;

    A propriedade Next, também não poderia ser usada?

    Qual a diferença entre as duas?

    1. Olá, Rodrigo, tudo bem?

      Ótima pergunta! Quando um registro de um DataSet é excluído (utilizando a instrução Delete), o cursor do DataSet se move automaticamente para o próximo registro, portanto, não há a necessidade de utilizar o Next. Na verdade, ao utilizar o Next, pela lógica, estaríamos pulando 1 registro.
      Para ficar mais fácil, considere que temos 3 registros em um DataSet:
      Registro 1 < -- Registro 2 Registro 3
      O cursor do DataSet está apontando para o "Registro 1". Ao utilizar o Delete, o "Registro 1" deixa de existir e o cursor se move para o "Registro 2":
      Registro 2 < -- Registro 3
      Logo, se utilizarmos o Next, o cursor se moverá para o "Registro 3", ou seja, pularíamos o "Registro 2".
      Vale ressaltar que essa operação só é adequada quando não for preciso utilizar os mesmos registros futuramente, já que eles serão excluídos. Caso a intenção seja apenas percorrer os registros do DataSet, o correto é utilizar o Next.

      Espero que tenha ficado claro! Abraço!

  19. Show de bola, estava usando um next e o dataset nunca chegava ao final e não saia do loop: while not cdsTemp.eof. Troquei pra delete e funcionou! Muito obrigado! VC é fera.

  20. Oi André achei muito interessante e proveitoso o artigo e preciso de uma ajuda pois sou iniciante, quero criar uma aplicação (já estou criando em Delphi mesmo) e tenho que levá-la ao Pc de outra pessoa só que na condição de não ter nenhuma ferramenta instalada lá,(tipo o software da receita federal, você já viu ?), onde o mesmo usa arquivos Xml como banco de dados, então, o Pc da pessoa não pode ter nada instalado, simplesmente só levo meu programa e instalo nele, como se fosse qualquer um baixado da web.
    Pelo amor de DEUS me ajude pois a tempos venho quebrando a cabeça e perdendo tempo em sites, blogs e outras fontes falsas de ensino.
    Desde já agradeço e que DEUS o abençoe…

  21. Obrigado por responder André, vamos lá : 1° – Quero muito saber como criar um programa e seu instalador, como eu já disse igual ao da ‘ Receita Federal ‘ com banco em xml (Aplicação mais leve e menor) , 2° – A aplicação que estou aprendendo a desenvolver usa como banco o MySQl 5, o ZeosLib e o Delphi que eu uso é o Rad Studio XE2 update4. Mas desculpe minha ignorância mas não adianta só saber o que tem que levar para o outro Pc e sim como faze-lo. Resumindo quero chegar no Pc do cara que não tem o MySQl 5, o ZeosLib e nem o Delphi que eu uso que é o Rad Studio XE2 update4 nem dll nenhum instalado, clicar no setup do meu programa e ele fazer o resto. Já tentei dicas com installshield wizard, inno setup e muitos outros e nada, pois nunca achei ninguém que desse a dica passo a passo na web e quando acha é perca de tempo.
    Disculpa algo que me espressei errado, e desde já agradeço a atenção e que DEUS

  22. Boa tarde André !

    Em relação a chave estrangeira, tenho 3 chaves 1 para pedido 1 para item e 1 para produto, a do pedido funciona bem, o problema é que cada registro pode ter apenas item ou produto. Se uma das duas chaves estrangeiras ficar vazia não consigo puxar os registros em um DBGrid quando alterno de “Pedido” no DBGrid principal. Você conhece alguma solução ? Minha intenção é evita o máximo possível de código por isso não sei se conseguiria usar o Temporário. Abraços.

  23. André, achei muito interessante o artigo e parabéns pelo mesmo. Até fiz um exemplo aqui e deu certo. Agora tenho uma aplicação que é distribuída gratuitamente. Por esse motivo usei o banco de dados firebird (fácil instalação) e tenho um problema quanto ao conteúdo do banco que não pode ser copiado por terceiros. Pensei em cryptografar os dados no banco firebird e quando o programa abrir jogar os dados numa tabela virtual e descrytografado para servir a pesquisa quando abrir o programa (ele só serve para pesquisa), só que fica lento o processo de copiar os dados para tabela virtual. Tem alguma sugestão de como faço para preservar meus dados no banco, só lembrando que a instalação do banco tem que ser fácil, porque muitas pessoas leigas instalarem esse programa.

    1. Olá, Flavio, tudo certo?
      Ainda não tive a oportunidade de trabalhar com dados criptografados da forma que você mencionou (descriptografar ao abrir o programa). O processo realmente pode ficar lento, já que é necessário percorrer todos os dados, descriptogrando-os e os atribuindo à uma tabela virtual. Porém, eu tenho outra sugestão: ao invés de utilizar criptografia, já considerou a possibilidade de alterar o usuário e senha do seu banco de dados? Isso significa que, mesmo que o arquivo seja copiado por terceiros, as informações não serão exibidas por questões de segurança.
      Por outro lado, se você precisa da criptografia, eu recomendo que você altere o comportamento do programa para descriptografar os dados somente quando o usuário pesquisar por algum registro. Dessa forma, apenas o que foi pesquisado (poucos registros) serão descriptografados, e não uma tabela inteira, evitando a lentidão que você mencionou.

      Espero ter ajudado!
      Abraço!

  24. André, como é uma aplicação que vai ser distribuída gratuitamente ela terá que ser de fácil instalação para usuários leigos. Eu ainda não achei um banco de dados de fácil instalação e que seja seguro por um banco de dados com senha. E para complicar mais um pouco eu trabalho com dois dbgrids na tela inicial, fornecendo pesquisa – é um programa que é uma agenda eletrônica, então em um grid pesquiso empresa por nome ou telefone, no outro pesquisa produtos dessas empresas. As empresas que compram a propaganda ficam em primeiro lugar e assim vai. O dbgrid fica conectado direto e mostra 13 empresas que fizeram propaganda. Se você tiver uma sugestão de banco de dados seguro com senha e fácil instalação eu ti agradeço a sugestão. Obrigado pela atenção.

    1. Olá, novamente, Flavio!
      Um banco de dados das características que você mencionou (leve, seguro e de fácil instalação) é o Firebird, no qual você já havia falado que utilizou. A instalação leva aproxidamente 30 segundos e a pasta ocupa pouco menos de 30MB no computador. Além disso, conforme citei no comentário anterior, é possível configurar uma senha para o banco de dados (arquivo FDB), de forma que, mesmo que outra pessoa com o Firebird instalado tenha acesso ao arquivo, não conseguirá ler as informações.
      Há algum tempo publiquei um artigo sobre distribuição de aplicativos com Firebird. Confira:

      http://www.andrecelestino.com/distribuindo-uma-aplicacao-com-firebird/

      Muitos programadores também comentam sobre o SQLite, porém, ainda não tive a oportunidade de utilizá-lo em um projeto.
      Abraço!

  25. Ótimo, gostei realmente não sabida desta possibilidade, isso vai resolver um problema de compatibilidade com o XE7, uso bde como tmp.
    Obrigado.

  26. Oi Andre, boa tarde.
    Parabens pelos artigos.
    Não li todos os comentarios, assim não sei se ja tem algum que tiraria minha duvida. Se puder me ajudar, ficarei grata.
    Uso uma aplicação cliente e outra servidora com soap. Ao abrir uma tabela vazia no cliente e esta possui master/detail (usando clientdataset) a aplicação demora a responder (o servidor e o banco de dados firebird estao numa máquina em outra cidade). Ha uma lentidão num simples open. Se a tabela nao for master/detail fica rapido (a sentença sql traz a tabela vazia where 1<1, por exemplo). Uso delphi xe5. Saberia me dizer como faço para resolver essa lentidao?
    Obrigada

  27. Olá Andre, tudo bem?
    Muito legal seu exemplo parabéns pela iniciativa.

    Estou montando uma tela onde vou simular o desconto de cheques.
    Numa tabela chamada CHEQUES, já tenho todos os cheques cadastrados.
    Preciso agora achar uma forma de inserir os cheques que eu selecionei, no clientdataset, pois fazer a inserção de 1 por 1 dá muita mão de obra pro usuario.

    Tem uma forma pratica de fazer isso?

    Obrigado.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Preencha o campo abaixo * Time limit is exhausted. Please reload CAPTCHA.