|
Usuários |
|
206 Usuários Online
|
|
[Artigos]
[Básico] - Tabela temporária com ClientDataSet – Prática |
Publicado por rboaro : Quarta, Abril 24, 2013 - 07:54 GMT-3 (691 leituras)
comentar Enviar para um amigo Versão para impressão
|
Olá, 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.

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

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.

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!
Link Original do Artigo:
ClientDataSet Tabelas Temporarias
|
|
Comentários | |
| | Comentários pertencem aos seus respectivos autores. Não somos responsáveis pelo seus conteúdos. |
|
|
Edição 112 |
|
|
50 Programas Fontes |
|
|
Produtos |
|
|