quinta-feira, 18 de abril de 2013

[Básico] - Tabela temporária com ClientDataSet – Conceito


Uma das vantagens de um fórum de programação é observar as dúvidas mais frequentes dos usuários e tentar ajudá-los de uma forma mais prática. Dessa vez, notei que muitos desenvolvedores têm dificuldades em compreender, criar e manipular tabelas temporárias no Delphi utilizando ClientDataSet. Além de ser um recurso muito útil, trabalhar com tabelas temporárias não exige conhecimentos avançados de programação.
Preparado pra mais um pequeno tutorial sobre desenvolvimento?

Tabela temporária? O que é isso?
Também conhecida como “tabela virtual”, uma tabela temporária é capaz de armazenar registros em memória sem a necessidade de estar conectada a um banco dados, diferentes das tabelas físicas, que armazenam os dados em disco. Os registros da tabela temporária são apagados automaticamente quando a aplicação é encerrada ou quando se utiliza um comando próprio pra isso, no qual veremos no próximo artigo. Um grande recurso da tabela temporária é permitir manipular estes dados em memória, como inclusões, alterações, exclusões e filtros, tal como podemos fazer com tabelas físicas no banco de dados.

Mas qual a vantagem de utilizar uma tabela temporária no meu projeto?
Bom, depende do tipo de projeto que você está desenvolvendo. Tabelas temporárias, em linhas gerais, são úteis para trabalhar com dados locais na aplicação de forma dinâmica. Por exemplo, em um ambiente master/detail, uma tabela temporária pode armazenar os registros filhos antes mesmo do registro mestre ser gravado no banco de dados.

Ainda não entendi. Poderia dar um exemplo?
Claro que sim.
Imagine que estamos desenvolvendo um sistema para controle de vendas.
No nosso banco de dados, teremos as seguintes tabelas relacionadas à venda:

-- Tabela VENDAS
COD_VENDA
DATA
COD_CLIENTE
TOTAL

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

Agora, suponha que iremos gravar uma nova venda no sistema com os seguintes dados:

COD_VENDA = 1
DATA = 15/02/2013
COD_CLIENTE = 20
TOTAL = ?

Ué, cadê o total?
Você deve concordar que, para informar o valor total, é necessário adicionar os itens, ou seja, precisamos somá-los para calcular o valor total da venda, não é? Por outro lado, para adicionar os itens precisamos do código da venda, já que as duas tabelas são relacionadas por uma chave estrangeira:

(ITENS.COD_VENDA = VENDAS.COD_VENDA).

Agora raciocine comigo: se tentarmos adicionar um item sem o código da venda ou com o código de uma venda que (ainda) não existe, receberemos o erro de “violação de chave estrangeira”, visto que, na verdade, tentaríamos adicionar um registro filho sem a existência do registro pai.
Pois bem, e para obtermos o código da venda, precisamos primeiro gravá-la no banco de dados, certo? Mas espere aí… conforme vimos acima, não temos o valor total pra gravar a venda!
E então entramos em um impasse:
- Não podemos gravar primeiro a venda, pois não temos os itens
- Não podemos gravar primeiro os itens, pois não temos a venda

E agora? Já sei! Vamos gravar a venda sem o valor total!
Muitos desenvolvedores utilizam essa “técnica”, se é que podemos chamá-la assim. Aplicando à nossa realidade, gravamos a venda sem o valor total, apenas para obter o código da venda. Dessa forma, podemos gravar os itens da venda normalmente, e após gravá-los, calculamos o valor total e alteramos o registro da venda, atualizando o total. Em um contexto procedimental, ficaria dessa forma:
Gravar a venda sem o valor total
Obter o código da venda gravada
Gravar os itens utilizando o código da venda obtido
Somar os itens para calcular o total
Editar a venda e atualizar o valor total
Observe que para cada venda será necessário fazer duas operações na tabela de vendas: uma de inserção e outra para alteração. Eu, particularmente, não sou de acordo com esse procedimento.
Em um exemplo, imagine que gravamos a venda, mas ao começar a adicionar os itens, a energia é cortada ou o usuário decide fechar a tela por algum motivo. Obviamente o registro ficará incompleto, já que teremos uma venda sem itens gravada no banco de dados. Tecnicamente, será um registro mestre sem registros filhos.
No caso da energia acabar, o problema pode ainda se agravar um pouco mais. Ao reiniciar o sistema, o usuário irá gerar uma nova venda, visto que, aos olhos do usuário, a outra venda não foi gravada. No fim da história haverá 2 vendas idênticas no sistema: uma sem itens (perdida) e outra válida.

Mas neste caso é só excluir essa venda incompleta, não é?
Sim, pode ser. Mas para isso, você terá que implementar um controle eficiente no seu sistema para identificar esses registros problemáticos. E também, lembre-se que cada vez que isso ocorrer, o código da venda será perdido (“pulado”) no banco de dados.
Aí prepare-se para receber algumas ligações do usuário perguntando:
“Por quê o sistema pulou o número da venda?”
“A venda nº X sumiu do sistema…”
“Tem uma venda aqui sem itens!”

Certo, e qual a sugestão para resolver isso?
Opa, chegou aonde eu queria!
Amigos, todos os problemas citados acima podem ser resolvidos utilizando tabelas temporárias! Durante a inclusão da venda, ao invés de gravarmos os itens no banco de dados, iremos gravá-los em uma tabela temporária. Se a energia acabar, nada será afetado, já que nenhuma alteração foi feita no banco de dados.
Este será o nosso procedimento:
Inserir os itens na tabela temporária;
Ao gravar a venda, os itens da tabela temporária serão “copiados” para a tabela física, tudo em um mesmo método.
Desta maneira, iremos reduzir bastante a possibilidade de uma venda ficar incompleta, visto que a gravação da venda e os itens da venda acontecerão praticamente ao mesmo tempo. E o melhor: durante a inclusão da venda não faremos nenhuma operação no banco de dados, somente na gravação.


Nenhum comentário:

Postar um comentário