Escolar Documentos
Profissional Documentos
Cultura Documentos
(Parte I)
A programao Cliente/Servidor envolve vrios conceitos, os quais, partem da escolha do banco de dados a
ser acessado, o qual, obrigatoriamente, deve ser um SGBD (Sistema Gerenciador de Banco de Dados
Interbase, SQL Server, Oracle e outros). O simples fato de se utilizar um banco de dados Local (Access,
Paradox, Dbase e outros) tira o ttulo de Cliente/Servidor de um sistema.
O SGBD imprescindvel pelo simples fato do mesmo ter a capacidade de processamento do lado Servidor,
isto , todas as requisies de servios feitas a este banco de dados sero processadas no servidor de banco
de dados e no na estao que fez a requisio, que o que acontece com os bancos de dados Locais, pois
estes servem apenas para armazenamento de informaes. Alm desta vantagem os SGBDs tem outras
caractersticas peculiares a eles, mas este no o enfoque desta matria, sendo assim, vamos adiante.
O esquema abaixo representa um acesso a um SGBD na maneira mais antiga, onde necessitamos de uma
Middleware (camada intermediria de acesso BDE, ODBC, etc...) para o acesso a este banco de dados.
Mesmo sendo uma maneira antiga de acesso algumas empresas ainda mantm esta metodologia de trabalho
por pura falta de tempo ou preguia de converter os sistemas, pois a tecnologia que substituiria esta j se
encontra disponvel no mercado a bastante tempo.
Iremos analisar agora o que precisamos em nosso sistema para que tal esquema no perca suas
caractersticas de Cliente/Servidor.
Para comear no podemos se quer pensar em utilizar um objeto TTable, j que o mesmo foi criado
especificamente para acessos a bancos de dados Locais. Sua engenharia de acesso faz com que a
Middleware seja a responsvel pelo processamento das solicitaes de servios feitas ao servidor, no
utilizando assim os recursos do servidor.
Ento utilizaremos o objeto TQuery, este sim desenvolvido para acessos a SGBDs. O objeto TQuery possui
uma propriedade chamada SQL na qual definimos uma instruo, em linguagem SQL, para acesso ao SGBD o
qual tem a capacidade de interpretao desta linguagem, fazendo assim com que o sistema fique mais rpido
em seu processamento e flexvel em seu desenvolvimento.
Mas, este objeto retorna um pacote de dados Read-Only (somente para leitura), no suprindo ento as
necessidades de manipulao de dados (incluso, alterao e excluso), servindo somente para consultas. Isto
no bem verdade, pois um TQuery pode sim fazer manipulao de dados.
Ns temos a opo de habilitar a propriedade RequestLive do objeto o que no recomendado, pois isto far
com que o objeto TQuery trabalhe como se fosse um TTable, isto , ficando dependente da Middleware.
Partiremos ento para segunda opo e que a mais aconselhada. J que o SGBD tem a capacidade de
interpretao de instrues em linguagem SQL ideal que se utilize deste benefcio para uma melhor
performance de nosso sistema. Para tanto precisaremos de um outro objeto do tipo TUpdateSQL. O nosso
objeto TQuery dever ser ligado a este objeto pela propriedade UpdateObject.
Aps os dois estarem conectados devemos especificar as instrues de incluso, alterao e excluso em
linguagem SQL dentro do objeto TUpdateSQL, atravs das propriedades DeleteSQL, InsertSQL e
ModifySQL. Para os que no possuem conhecimentos de linguagem SQL para tanto e para aqueles
preguiosos assim como eu, temos ainda uma opo mais fcil para tal tarefa que se inicia por darmos um
duplo-click no objeto TUpdateSQL que quando se abrir uma caixa de dilogo, nesta percebemos duas
pastas : Options e SQL. Na pasta Options temos um combobox onde ser exibido o nome da tabela a qual o
objeto TQuery est acessando (isto definido a partir da instruo SQL do TQuery ). Abaixo deste combobox
temos alguns botes :
SelectPrimaryKeys o qual define o(s) campo(s) chave da tabela de acordo com as especificaes
da mesma no banco de dados e
Caso o programador queira e tenha o conhecimento necessrio para tanto, ele pode alterar estas instrues,
mas no necessrio, pois as mesmas funcionam como so geradas.
Na pasta Options ainda temos dois listboxs onde so exibidos, no da esquerda (KeyFields) o(s) campo(s)
chave da tabela e no da direita (UpdateFields) os campos que tero seus valores alterados, includos e/ou
excludos pelas instrues em linguagem SQL.
Aps estes procedimentos, que , no momento da leitura parecero demorados, porm na prtica so muito
simples, o nosso TQuery est quase pronto para ser utilizado para manipulao de dados faltando apenas um
passo mnimo mas de extrema importncia, sem o qual no funcionar.
Basta agora habilitar a propriedade CachedUpdates do TQuery. Esta propriedade faz com que todas as
alteraes (incluso, alterao ou excluso) feitas nos dados sejam armazenadas na memria da mquina
cliente (estao de trabalho), j que isto tambm faz parte do modelo Cliente/Servidor de desenvolvimento de
sistemas. Isto mesmo, o acesso aos dados ou o envio das alteraes realizadas nos mesmos para o banco de
dados no modelo Cliente/Servidor no devem ser realizadas simultaneamente, isto , o acesso ao banco de
dados deve ser minimizado ao mximo. Os dados s devem ser enviados ao servidor quando os mesmos j
estiverem totalmente prontos para tanto, devidamente alterados e condicionados pelas regras que regem o
negcio do sistema, para evitar trfego desnecessrio de dados pela rede e processamentos que gerem erros
de tratamento no SGBD, mantendo assim o servidor sempre disponvel para os demais acessos.
Agora sim seu TQuery est funcionando a toda carga. Consultando, alterando, incuindo e excluindo dados.
E a maneira com que o cdigo ser gerado para isso ? Ser o mesmo cdigo que voc usaria com uma TTable:
Append, Edit, Delete, Post, Cancel. A nica diferena que ns estamos trabalhando com os dados em
memria e, em algum momento, estes dados devero ser enviados ao servidor, para isso basta aplicar um
mtodo ApplyUpdates no objeto TQuery. O momento ideal para isto depender do seu negcio, geralmente
isto realizado aps cada post ou delete.
OBS.: As manipulaes dos dados sero feitas atravs do objeto TQuery, j que ele o responsvel pela
persistncia dos dados em memria. Ento os mtodos relacionados acima dizem respeito a este objeto e no
ao TUpdateSQL.
importante enfatizar que os conceitos Clietne/Servidor no param por a, existe tambm a questo do
controle de transaes no banco de dados, realizado, neste caso, pelo objeto TDatabase, atravs dos mtodos
StartTransaction (incio de transao), Commit (confirmao de transao) e Rollback (Cancelamento de
transao). Uma transao deve ser iniciada sempre antes de se enviar os dados para o SGBD e a
confirmao logo aps este envio.
Para um melhor entendimento destas transaes no SGBD, leia a matria sobre Introduo Bancos de
Dados, tambm escrita por mim.
Quaisquer dvidas sobre esta matria estarei disponvel para esclarecimentos atravs do email
lambertidgdt@aol.com.
Programao Cliente/Servidor
(Parte II)
Na primeira parte deste artigo vimos um modelo antigo de desenvolvimento com tecnologia
Cliente/Servidor, o que equivaleria ao desenvolvimento na verso 5.0 do Delphi ou anterior.
A partir de agora iremos utilizar os recursos disponibilizados nas verses 6.0 e posteriores
do Delphi, mas precisamente na verso 7.0, a que a mais atual, j que na verso 8.0 foi
implementada a tecnologia .NET, a qual no se encontra 100% estvel.
Vocs iro reparar que no existem diferenas no que diz respeito aos conceitos
Cliente/Servidor e na prtica tambm no ser difcil de se desenvolver, j que a arquitetura
de desenvolvimento Cliente/Servidor se mantm a mesma, com alguns objetos diferentes.
A partir de agora nosso esquema de conexo com o banco de dados ir mudar um pouco,
mas no para melhor. Calma no precisa se desesperar, a metodologia ser a mesma, as
nicas coisas que iro mudar a princpio sero os objetos de conexo.
No modo antigo de conexo ns dependamos de uma Middleware, o que nos tomava tempo
na implementao e na manuteno dos nossos sistemas, pelo simples fato de que na
implementao de nossos sistemas na rede, era obrigatria a instalao da camada
intermediria de acesso (Middleware) em todas as estaes da rede, o que nos tomava
muito tempo e, caso acontecesse algum problema nesta (seja por atualizaes de drivers ou
problemas fsicos - usurio) devamos reinstalar a Middleware ou simplesmente copiar o
driver de conexo da mesma.
Agora esta Middleware ser extinta juntamente ao TDatabase, pois entrar em seus
lugares um objeto do tipo TSqlConnection (palheta de objetos dbexpress), o qual, alm de
conter os drivers de acesso a banco de dados, tambm ir fazer o controle das transaes.
muito simples desenvolver sistemas desta maneira, a primeira coisa que deve ser sabida
para tanto que os objetos citados devero estar sempre no mesmo ambiente, isto , no
mesmo formulrio, sendo utilizado para isto, geralmente um TDataModule, que no passa
de um centralizador de objetos de conexo ao banco de dados.
Nesta tela basta configurar a propriedade Database, no lado esquerdo da tela, onde se
encontram as configuraes de acesso, para que o seu driver passe a acessar o banco
desejado.
OBS.: No caso do driver do Interbase, o nome do arquivo .GDB se precede do caminho
completo (IP:Drive:\caminho\arquivo.gdb).
Para testarmos esta conexo basta clicar no boto Test Connection, que se encontra na
barra de botes desta tela (segundo da direita para a esquerda). Caso ocorra tudo bem
partimos para o prximo passo.
Propriedades
CommandText : indicar a instruo SQL que ir acessar a(s) tabela(s) do banco de dados.
Propriedade
DataSet : indicar a qual TSQLDataSet este objeto ir se conectar para prover os dados para
a persistncia.
Propriedade
Propriedade
DataSet : indicar a qual TClientDataSet este estar linkado para a liberao visual dos dados
para interao com o usurio.
OBS.: importante tomar cuidado na hora de conectar o TDataSource ao TClientDataSet,
pois na lista que aparece na propriedade de conexo aparecero tambm os objetos do tipo
TSQLDataSet.Caso a conexo seja feita ao objeto errado o resultado esperado no ser
alcanado. Caso isto acontea revise todas as conexes realizadas.
Pronto, basta conectar seus TDataControls ao seu TDataSource que seu sistema estar
funcionando.
Em relao ao cdigo que ser gerado para a manipulao de dados, no teremos muitas
diferenas. Para ativar a conexo do sistema com o banco de dados, iremos abrir o nosso
objeto TSQLConnection, assim como fazamos com o objeto TDataBase. Para
manipularmos os dados iremos aplicar todos os mtodos que j aplicvamos anteriormente :
Insert, Delete, Update, Post, ApplyUpdates, etc..., sendo que, no a partir de um objeto
TQuery e sim a partir do objeto TCllientDataSet, isto mesmo, o objeto TClientDataSet o
responsvel pela persistncia de dados, ento ser a partir dele que iremos manipular os
dados, aplicando o mtodo de acordo com a operao desejada. No que diz respeito aos
objetos TSQLDataSet e TDataSetProvider, no necessrio que se invoque estes, via
cdigo, em nenhum momento, pois toda operao realizada no TClientDataSet
automaticamente repassada para os objetos de conexo anteriores a ele (TDataSetProvider
e TSQLConnetion), de acordo com a funcionalidade do mtodo invocado.
Como de costume nestes artigos, vamos manter um padro, primeiro falando sobre a
programao com query e depois falando sobre os SqlDataSets, DataSetProviders e
ClientDataSets.
Voc achou estranho esta condio criada na instruo sql ? Deve estar se perguntando :
Se pra colocar um parmetro para filtrar os itens do pedido via cdigo eu no precisaria ter
este trabalho todo ? Ento eu lhe responderei, este parmetro ser automaticamente
alimentado por causa do relacionamento entre as Querys atravs do DataSource, isto ,
sempre que for filtrado um pedido na QryPedidos, automaticamente os itens deste pedido
sero filtrados por conta do relacionamento. Isto no quer dizer que, em uma eventual
manipulao (incluso), os itens sero automaticamente associados ao pedido em questo,
a passagem do nmero do pedido para o item dever ser feito manualmente, isto
geralmente realizado no evento before post da QryItens.
Outro ponto muito importante a ser abordado neste relacionamento ser no momento de se
aplicar, no banco de dados, as alteraes realizadas na memria da mquina cliente, j que
nossa query est trabalhando com cachedupdates habilitado. A rotina abaixo enfatiza
perfeitamente este momento :
QryItens.DataSource := nil;
If QryPedidos.State in [dsInsert, dsEdit] then
begin
QryPedidos .ApplyUpdates;
QryItens.ApplyUpdates;
end
else
begin
While not QryItens.Eof do QryItens .Delete;
QryPedidos.Delete;
QryItens.ApplyUpdates;
QryPedidos .ApplyUpdates;
end;
QryItens.DataSource := DsPedidos;
A primeira linha deste cdigo (QryItens.DataSource := nil;) indica que estamos desabilitando
o relacionamento entre as Querys, porque a Query, quando trabalhando em memria
(cachedupdates = true), se atualiza automaticamente aps o envio das alteraes
(incluses, alteraes e/ou excluses) da memria da Query para o banco de dados.
Por exemplo : Caso eu envie uma incluso para o banco de dados com o relacionamento
ainda vigorando, a QryPedidos se atualizaria automaticamente aps este envio
(QryPedidos .ApplyUpdates;) e, devido ao relacionamento, os itens daquele pedido seriam
retornados para QryItens, isto , no retornaria nenhum registro para a QryItens porque, no
banco de dados, ainda no existe nenhum item cadastrado para o mesmo e a QryItens seria
esvaziada, quer dizer, os registros existentes no momento da incluso seriam substitudos
pelos registros retornados do banco de dados (nenhum), sendo assim perdidos os registros
que o usurio havia cadastrado.
Por este motivo devemos desfazer o relacionamento entre as Querys antes de enviar os
dados para o banco de dados e, aps o envio destes dados, realizar a operao inversa,
refazendo o relacionamento, o que feito na ltima linha do procedimento
(QryItens.DataSource := DsPedidos;).
Em uma incluso devemos enviar primeiro os dados da tabela pedidos (PAI), pois o
relacionamento no banco de dados atravs de uma Foreign-Key (chave-estrangeira) nos diz
que um Item (FILHO) s pode ser gravado relacionando-o a um pedido (PAI) que j exista, e
em uma excluso feito o contrrio, pois este relacionamento tambm diz que um pedido
(PAI) que tem itens (FILHO) relacionados a ele no pode ser excludo, portanto devemos
excluir primeiro da tabela de itens, o que perfeitamente feito na rotina acima.
Agora que terminamos a parte onde explanamos o relacionamento entre Querys irei agora
demonstrar como seria realizado este relacionamento entre os objetos da palheta
DbExpress (Delphi 6, 7), para tanto deveremos ter em nosso data module, alm do objeto
SqlConnection devidamente configurado, um objeto SqlDataSet renomeado para SqlPedidos
e outro renomeado para SqlItens e, em suas propriedades ComandText as mesmas
instrues utilizadas nas querys. A exemplo do relacionamento entre querys o SqlItens
dever estar conectado ao DataSource do SqlPedidos atravs da propriedade DataSource.
Quaisquer dvidas sobre esta e outras matria escritas por mim, entrem em contato pelo
email lambertidgdt@aol.com.
Abraos
Flvio Lamberti
Programao Cliente/Servidor
(Parte IV)
QryItens.DataSource := nil;
DataBase.StartTransaction;
If QryPedidos.State in [dsInsert, dsEdit] then
begin
QryPedidos .ApplyUpdates;
QryItens.ApplyUpdates;
end
else
begin
While not QryItens.Eof do QryItens .Delete;
QryPedidos.Delete;
QryItens.ApplyUpdates;
QryPedidos .ApplyUpdates;
end;
Database.Commit;
QryItens.DataSource := DsPedidos;
A segunda linha do cdigo acima ordena ao objeto Database que o mesmo inicie uma
transao no banco de dados, atravs do mtodo StartTransaction e a penltima linha do
cdigo faz com que o mesmo objeto Database finalize a transao iniciada anteriormente
atravs do mtodo Commit.
importante enfatizar que o objeto Database trabalha com apenas uma transao aberta
por vez, no aceitando assim a execuo de dois mtodos StartTransaction
consecutivamente.
Isto far com que os dados sejam agrupadas em uma nica transao no banco de dados,
minimizando os riscos de perda de informaes.
Agora vamos ver como ficaria o mesmo controle de transaes atravs dos objetos da
palheta DbExpress.
A funo do objeto SqlConnection o controle de transaes no banco de dados, alm da
conexo com o mesmo. Repare que o cdigo no ter muitas alteraes de cdigo.
Repare que os mtodo de incio e fim de transaes so os mesmos utilizados com o objeto
Database, sendo que necessrio que se passe um parmetro em sua execuo. Este
parmetro indica qual transao est sendo iniciada e qual est sendo finalizada. Isto
mesmo o objeto SqlConnection aceita o controle mutiplo de transaes, caso voc tenha a
necessidade de trabalhar com mais de uma transao aberta ao mesmo tempo.
No cdigo relacionado acima, a transao que iniciada e finalizada logo a seguir, chamada
de TD, na verdade uma varivel do tipo TtransactionDesc, geralemente declarada no Data
Module de sua aplicao, e configurada no evento OnCreate do mesmo. A configurao
simples, j que a varivel declarada como sendo uma classe, ela automaticamente herda
todas as propriedades, mtodos e eventos desta, sendo assim basta usar o cdigo abaixo:
TD.TransactionId := 1;
TD.IsolationLevel := xilReadCommited;
Caso seja sua necessidade trabahar com duas transaes em aberto ao mesmo tempo onde
uma independa da outra, basta criar outra varivel do mesmo tipo e configur-la com o
TransactionId = 1, ou com o identificador diferente dos demais.
Como sempre, espero ter ajudado, e continuo a disposio para tirar as possveis dvidas
relativas aos artigos por mim redigidos atravs do email lambertidgdt@aol.com, para outras
dvidas quaisquer, acessem o forum do site www.clubedelphi.com.br.
Abraos
Flvio Lamberti