Professional Documents
Culture Documents
Delphi
ndice Analtico
INTRODUO AO MODELO CLIENTE/SERVIDOR..................................................................
Mudanas de Paradigmas.......................................................................................................................
Paradigma Computacional.................................................................................................................
Paradigma do Negcio........................................................................................................................
Evoluo da Arquitetura.........................................................................................................................
Arquitetura Time-Sharing....................................................................................................................
Arquitetura Resource-Sharing.............................................................................................................
Arquitetura Cliente/Servidor...............................................................................................................
Primeira Gerao Cliente/Servidor........................................................................................................
Segunda Gerao Cliente/Servidor.........................................................................................................
SGDB - SISTEMAS GERENCIADORES DE BANCO DE DADOS..............................................
Modelos de Banco de Dados...................................................................................................................
Sistema de Gerenciamento de Arquivos..............................................................................................
Banco de Dados Hierrquico..............................................................................................................
Banco de Dados de Rede.....................................................................................................................
Banco de Dados Relacional................................................................................................................
BANCOS DE DADOS RELACIONAIS..............................................................................................
Classificao...........................................................................................................................................
Corporativos........................................................................................................................................
Departamentais....................................................................................................................................
Locais ou Mveis.................................................................................................................................
Modelagem de Dados..............................................................................................................................
Normalizao.......................................................................................................................................
Propagao de chaves primrias........................................................................................................
Ferramentas.........................................................................................................................................
Criao da Base de Dados..................................................................................................................
Utilizando Interbase Windows ISQL...................................................................................................
Linguagem SQL......................................................................................................................................
Categorias da Linguagem SQL...........................................................................................................
Utilizando o Windows ISQL para definir o Banco de Dados.............................................................
Utilizando o Windows ISQL para acessar o Banco de Dados............................................................
Consistncia e Integridade dos Dados....................................................................................................
Integridade Referencial.......................................................................................................................
Domnio dos dados..............................................................................................................................
Regras de Negcio...............................................................................................................................
Utilizando o Windows ISQL para definir integridades e consistncias.............................................
Utilizando o Windows ISQL para testar as consistncias..................................................................
Distribuio da Consistncia e Integridade dos Dados.....................................................................
SQL EXPLORER..................................................................................................................................
Criao de Alias......................................................................................................................................
Visualizao e Edio de Dados.............................................................................................................
Definio de novos elementos................................................................................................................
Definio de Dicionrios de dados.........................................................................................................
Introduo ao Modelo
Cliente/Servidor
Esse captulo mostra a evoluo na
arquitetura de computadores e a tendncia a
ambientes de aplicaes cada vez mais
distribudos.
Captulo
Mudanas de Paradigmas
Paradigma Computacional
A viso tradicional da computao era centralizada na figura do
computador. que concentrava todos os servios e recursos fornecidos
aos usurios. O acesso a esses computadores era feito diretamente
pelo usurio atravs de teclados e monitores. Em alguns casos, essa
mquina era um equipamento poderoso capaz de atender vrios
usurios simultaneamente (Mainframe). Ou ento, eram pequenos
computadores isolados capazes de atender um nico usurio de cada
vez.
Delphi Client/Server
I N T R O D U O
A O
M O D E L O
C L I E N T E / S E R V I D O R
Fig. 1.1: Arquitetura de Mainframe esquerda e um computador PC isolado direita. Ambos simbolizam a
viso computacional tradicional, onde o foco o computador.
Delphi Client/Server
I N T R O D U O
A O
M O D E L O
C L I E N T E / S E R V I D O R
Web
Informao
Dados
Rede
Data
WareHousing
Fig 1.2: As redes interligam os computadores fornecendo servios e recursos de forma escalar e
transparente para os usurios finais.
Fig 1.3: Globalizao da economia. A empresas atuam mundialmente, no havendo mais limites geogrficos
para a competitividade.
Uma ateno especial deve ser dada aos clientes que exigem
produtos cada vez mais especficos e personalizados. Para suportar
essa presso competitiva do mercado, os gerentes de negcio devem
estar munidos de informaes e ferramentas que os permitam tomar
Delphi Client/Server
I N T R O D U O
A O
M O D E L O
C L I E N T E / S E R V I D O R
Informao
Evoluo da Arquitetura
O objetivo da arquitetura cliente/servidor proporcionar um
ambiente capaz de compartilhar os recursos e servios de vrias
mquinas interligadas e prover uma maneira cooperativa de executar
as aplicaes dos usurios finais.
A seguir sero mostradas algumas arquiteturas para explicar a forte
tendncia a ambientes distribudos cooperativos.
Arquitetura Time-Sharing
Essa arquitetura baseada em um processamento centralizado. Uma
mquina, chamada de hospedeiro, responsvel por rodar todos os
programas e gerenciar
todos os recursos. O tempo de
processamento compartilhado pelos programas, simulando uma
execuo em paralelo. Os usurios tm acesso a esses servios e
recursos atravs de terminais conectados localmente ou
Delphi Client/Server
I N T R O D U O
A O
M O D E L O
C L I E N T E / S E R V I D O R
Processamento
Arquitetura Resource-Sharing
Essa arquitetura consiste de vrios computadores (estaes de
trabalho) interligados, sendo cada um capaz de realizar seu prprio
processamento. Alguns desses computadores so responsveis em
compartilhar e gerenciar recursos tais como impressora, disco, etc
(servidores de rede).
Entretanto, a rede no utilizada para proporcionar um
processamento
cooperativo
entre
as
mquinas.
Todo
o
processamento da aplicao ainda feito por uma nica mquina,
havendo apenas o compartilhamento de recursos. Atravs dessa
arquitetura possvel compartilhar a base de dados da aplicao,
permitindo o acesso por vrias pessoas simultaneamente. Mas como
todo o processamento dos dados realizado em cada mquina, a
necessidade de um volume maior de informaes torna invivel o
trfego de informaes pela rede. Para resolver esse problema seria
necessrio que a mquina responsvel em armazenar os dados
fizesse um processamento local capaz de enviar uma quantidade
menor de dados para a mquina que est processando a aplicao.
Delphi Client/Server
I N T R O D U O
A O
M O D E L O
C L I E N T E / S E R V I D O R
Servidor de Rede
Aplicaes
Processamento
Processamento
Fig. 1.6: Arquitetura Resource-Sharing.
Arquitetura Cliente/Servidor
Essa arquitetura tambm consiste de vrios computadores, cada um
com seu prprio processamento, interligados em rede. A diferena
bsica para a arquitetura Resource-Sharing que aqui j comea a
haver um processamento distribudo cooperativo. Parte do
processamento, que era feito pela mquina da aplicao, feito
agora pela prpria mquina responsvel pelo armazenamento e
distribuio da informao, diminuindo assim o trfego de
informaes na rede. Portanto, pode-se e deve-se selecionar os dados
que sero enviados para o usurio para uma melhor eficincia do
ambiente.
Esse modelo j comea a retirar partes especficas de processamento
das aplicaes que eram executadas pelas mquinas clientes,
centralizando-as nas mquinas de localizao fsica mais adequada,
garantindo assim uma melhor distribuio do processamento e
utilizao do ambiente. Atravs dessas especializaes garante-se
tambm um melhor gerenciamento e facilidade de manuteno dos
servios devido a sua concentrao em um ou poucos locais fsicos.
Delphi Client/Server
I N T R O D U O
A O
M O D E L O
Servidor de Banco
de Dados (DBMS)
C L I E N T E / S E R V I D O R
Servidor de Rede
Processamento
Processamento
Processamento
Aplicaes
Processamento
Fig. 1.7 Arquitetura Cliente/Servidor.
Podemos citar alguns benefcios que esta nova arquitetura traz para
o ambiente computacional das empresas:
Permite s corporaes alavacarem a tecnologia de computadores
desktops. Hoje, as estaes de trabalho j possuem um poder
computacional considervel, por um custo muito mais baixo, antes
s disponvel em Mainframes.
Permite que o processamento seja feito mais prximo da origem
dos dados reduzindo o trfego na rede.
Facilita a utilizao de aplicaes grficas e multimdias. Isto
permite a construo de aplicaes que excedem as expectativas
dos usurios proporcionando-lhes um real aumento de
produtividade.
Permite e encoraja a utilizao de sistemas abertos, j que clientes
e servidores podem rodar em diferentes hardwares e softwares,
livrando as corporaes de arquiteturas proprietrias.
Entretanto, essa arquitetura ainda no perfeita. Algumas
caractersticas necessrias para um completo processo distribudo
ainda no foram observadas nesse modelo que ainda apresenta
algumas deficincias:
Delphi Client/Server
I N T R O D U O
A O
M O D E L O
C L I E N T E / S E R V I D O R
I N T R O D U O
A O
M O D E L O
C L I E N T E / S E R V I D O R
Delphi Client/Server
I N T R O D U O
A O
M O D E L O
C L I E N T E / S E R V I D O R
SGDB - Sistemas
Gerenciadores de Banco de
Dados
Esse captulo apresenta os sistemas
gerenciadores de banco de dados, seus
servios, recursos e modelos.
Captulo
Delphi Client/Server
10
11
Raiz
1
20/10/96 15,00
Ana
Maria
Caneta
10
10,00 5
999.876.555-22
Lpis
2
21/10/96 65,00
111.111.111-22
5,00
3
Maria
Jos
15
Caneta
15,00
Caderno
5
50,00
Delphi Client/Server
12
Raiz
1
Ana
Maria
Lpis
Caneta
Caderno
Maria
Jos
111.111.111-22
999.876.555-22
Delphi Client/Server
13
Pedido
NumPed
1
2
3
Itens
Data
20/10/96
21/10/96
22/10/96
Valor
Cliente
15,00
65,00
25,00
1
2
2
Cliente
Codigo
1
2
Nome
NumPed
Produto
1
1
2
2
3
3
Caneta
Lpis
Caneta
Caderno
Lpis
Caderno
CPF
Delphi Client/Server
14
Quantid. Valor
10
5
15
5
15
1
10,00
5,00
15,00
50,00
15,00
10,00
Bancos de Dados
Relacionais
Captulo
Classificao
Quanto a capacidade, recursos e facilidade de uso, os banco de dados
relacionais podem ser divididos em trs categorias: corporativos,
departamentais e locais. Em uma mesma empresa todas as
categorias podem coexistir e cooperar entre si para juntas formarem
uma poderosa base de dados distribuda.
Delphi Client/Server
15
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Corporativo
Departamentais
Locais
Corporativos
Sistema de banco de dados para atender toda a corporao. Os
principais sistemas dessa categoria so: DB2, Oracle, Sybase,
Informix e Ingres. Estes bancos devem ser capazes de armazenar e
manipular de maneira eficiente grandes volumes de dados e permitir
acesso rpido a um nmero elevado de usurios conectados ao
mesmo tempo. Devido a sua enorme capacidade, os preos desses
bancos so tambm mais elevados e normalmente necessitam de
profissionais especializados para configur-los e monitor-los no dia a
dia.
Departamentais
Sistemas de banco de dados capazes de atender as requisies de
dados a nvel de um departamento. Nesse patamar, existem bancos
de dados mais baratos e mais fceis de configurar, entre eles esto:
Interbase, SQLServer, SQLBase.
A maioria dos fornecedores de bancos de dados da categoria
corporativa esto tambm disponibilizando verses departamentais
para disputar esse mercado, trazendo como vantagem a possibilidade
de permanecer com o mesmo fornecedor em todos os nveis,
tornando o ambiente mais integrado. Por outro lado, as principais
vantagens dos bancos desenvolvidos especialmente para essa
plataforma so: a facilidade de configurao, o preo dos produtos e
a menor requisio de recursos de hardware.
Delphi Client/Server
16
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Locais ou Mveis
Sistemas de banco de dados capazes de rodar na mesma mquina
que a aplicao. Nessa categoria os principais requisitos so: ser um
banco de dados bastante leve que gaste poucos recursos do sistema
operacional e da mquina(memria, processamento, etc) e que no
necessite de gerenciamento podendo rodar basicamente com sua
configurao original.
Nessa categoria podemos citar os bancos Interbase, SQLBase e
SQLAnywhere. Os fornecedores corporativos tambm esto
descendo para esse nvel. Porm, para manter os bancos de dados
com os mesmos recursos tem sido difcil torn-los leves e fceis
suficientemente. Alguns fornecedores possuem at sistemas de
banco de dados diferentes para cada plataforma.
Como esses bancos so instalados na mesma mquina possvel sua
utilizao em notebooks. Isso permite as empresas manterem a
mesma tecnologia de banco de dados relacional em aplicaes
mveis, facilitando a integrao com a base corporativa da empresa.
Deve-se notar entretanto, que no est se fazendo uso da arquitetura
cliente/servidor nesse caso, j que a mesma mquina utilizada para
rodar o aplicativo e o sistema gerenciador de banco de dados. A
principal vantagem dessa utilizao sobre a utilizao de base de
dados de arquivos, que a ltima no possui recursos suficientes
para manter a integridade dos dados e das transaes. Os sistemas
gerenciadores de banco de dados so tambm menos factveis a
corrupo de dados e falhas do que os sistemas baseados em
arquivos onde o gerenciamento feito por cada aplicao. Outra
vantagem prover mais facilidade de integrao com as bases
departamentais e corporativas, por utilizarem a mesma tecnologia.
Entretanto, os SGDBs possuem um custo adicional e exigem uma
configurao de mquina melhor devido a um nmero maior de
camadas que tero que ser percorridas para se chegar ao dado.
Modelagem de Dados
Modelagem de dados o processo utilizado para definir a estrutura
do banco de dados atravs da distribuio dos dados nas tabelas.
Existem maneiras diferentes de se definir o mesmo conjunto de
dados, e uma boa modelagem de dados pode facilitar bastante o
desenvolvimento das aplicaes. Vamos ressaltar aqui, dois pontos
que devem ser observados na construo do modelo: o processo de
normalizao e a propagao de chaves primrias.
Delphi Client/Server
17
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Normalizao
Tcnica de anlise e organizao de dados que visa determinar a
melhor composio para uma estrutura de dados. Os principais
objetivos dessa tcnica so:
Eliminar anomalias que dificultam as operaes sobre os dados;
Minimizar as redundncias
inconsistncias;
os
conseqentes
riscos
de
Chave
D
C
D
C
Grupo
Repetitivo
Fig. 3.2: Presena de grupos repetitivos em uma tabela relacional.
Delphi Client/Server
18
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Estrutura Original
Nova Estrutura
*NumPed
*NumPed
DataPed
*NomeProduto
ValorPed
PreoProduto
NomeCliente Quantidade
CPFCliente
ValorItem
Fig. 34: Exemplo na primeira forma normal.
Delphi Client/Server
19
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Chave Composta
C depende de A e B
D depende s de A
Fig. 3.5: Modelo na 1FN mas no em 2FN. Presena de atributos dependentes funcionalmente de apenas
parte da chave primria.
*
D
Estrutura Original
Nova Estrutura
20
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
*NumPed
*NumPed
DataPed
*CodProduto
ValorPed
Quantidade
NomeCliente ValorItem
CPFCliente
*CodProduto
NomeProduto
PreoProduto
Delphi Client/Server
21
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Estrutura Original
Nova Estrutura
Pedido
*NumPed
DataPed
ValorPed
CodCliente
Cliente
*CodCliente
NomeCliente
CPFCliente
ItemPedido
*NumPed
*CodProduto
Quantidade
ValorItem
Produto
*CodProduto
NomeProduto
PreoProduto
Delphi Client/Server
22
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
ItemPedido
*NumPed
*CodProduto
Quantidade
ValorItem
Fig. 3.11: Tabela de Itens. Chave primria composta pela propagao das chaves primrias de outras
tabelas.
Hist Itens
*NumPed
*CodProduto
*Data
Fig 3.12: Tabela de Hist. Itens
23
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
ItemPedido
*NumPed
*NumSeq
CodProduto
Quantidade
ValorItem
Fig 3.13 Tabela de Itens com chave primria alternativa.
Hist Itens
*NumPed
*NumSeq
*Data
Fig 3.14 Tabela de Hist. De Itens.
24
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Delphi Client/Server
25
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Delphi Client/Server
26
S G D B
S I S T E M A S
G E R E N C I A D O R E S
UF
*UF_SG
UF_NM
CIDADE
*CID_CD
*UF_SG
CID_NM
CID_NUMHABITANTES
PESSOA
*PES_CD
PES_NM
PES_TP
PES_CGCCPF
PES_LOGRADOURO
PES_NUMERO
PES_COMPLEMENTO
PES_BAIRRO
CID_CD
UF_SG
CLIENTE
*PES_CD
CLI_LIMITECREDITO
CLI_DEBITO
D E
B A N C O
D E
VENDEDOR
*PES_CD
VEN_VENDAS
VEN_PERCCOMISSAO
VEN_COMISSAO
PEDIDO
*PED_CD
PED_DT
PED_VALOR
PED_TIPO
PES_CD_CLI
PES_CD_VEN
DAD O S
PRODUTO
*PRO_CD
PRO_NM
PRO_PRECO
PRO_ESTOQUE
ITEM
*PED_CD
*PRO_CD
ITE_VALOR
ITE_QUANT
Linguagem SQL
Para acessar os bancos de dados relacionais foi desenvolvida uma
linguagem chamada SQL. O Objetivo dessa linguagem fornecer
uma forma padro de acesso aos bancos de dados, no importando a
linguagem com que esses tenham sido desenvolvidos. Apesar da
tentativa de se tornar um padro (ANSI), cada fornecedor hoje possui
uma srie de extenses que tornam as vrias verses incompatveis
entre si. Por isso, no pense que uma aplicao construda para
acessar um determinado banco de dados de um fornecedor, ir
acessar tambm, sem qualquer modificao, o banco de dados de um
outro fornecedor. Isto s possvel se a aplicao utilizar somente a
parte comum (ANSI) da linguagem SQL, mas isto faz com que ela
perca vrios recursos importantes disponveis em cada verso SQL
de fornecedores diferentes. Alguns bancos de dados j suportam o
padro SQL ANSI-92 que j mais abrangente numa tentativa de
facilitar o processo de deixar transparente a base de dados utilizada
pela aplicao. Entretanto, alguns fornecedores ainda no fornecem
suporte ao SQL ANSI-92 de forma completa porque teriam que
alterar partes estruturais de seus sistemas gerenciadores.
Categorias da Linguagem SQL
A linguagem SQL se divide em trs categorias:
DDL ( Linguagem de Definio de Dados). Parte da linguagem com
comandos para criao das estruturas de dados como as tabelas,
colunas, etc. Ex: CREATE TABLE.
Delphi Client/Server
27
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Delphi Client/Server
28
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
ou
select PRO_CD,PRO_NM,PRO_ESTOQUE,PRO_PRECO from PRODUTO
Delphi Client/Server
29
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Tabela B
*a
b
c
Tabela A
*c
d
e
.
.
Fig 3.19: Integridade Referencial.
Delphi Client/Server
30
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Essa uma forma mais fcil, porm menos flexvel. Com apenas um
comando se define a integridade. Porm, alguns bancos no
suportam essa sintaxe ou a fornecem de maneira limitada somente
para regras do tipo Restrict. A maior vantagem dessa alternativa
sua simplicidade e por isso menos sujeita a erros de implementao.
Triggers
Delphi Client/Server
31
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
32
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Restrict
CIDADE
*CID_CD
*UF_SG
CID_NM
CID_NUMHABITANTES
Fig 3.20: Integridade Referencial
33
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
34
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
Delphi Client/Server
35
S G D B
S I S T E M A S
G E R E N C I A D O R E S
D E
B A N C O
D E
DAD O S
SQL Explorer
Esse captulo apresenta a ferramenta de
definio e manipulao de dados SQL
Explorer da Borland.
Captulo
Criao de Alias
Uma das possibilidades do SQL Explorer a definio de aliases.
Ao abrir o SQL Explorer exibido na lista Databases todos os
aliases definidos no BDE.
Delphi Client/Server
36
Delphi Client/Server
37
Delphi Client/Server
38
39
Delphi Client/Server
40
Delphi Client/Server
41
Delphi Client/Server
42
Delphi Client/Server
43
Captulo
Delphi Client/Server
44
B A N C O S
D E
DA D O S
R E L A CI O N A I S
CLIENTE
CLIENTE
MIDDLEWARE
Aplicaes
Ferramentas
Desenvolvimento
Servios Especficos
Database
DatabaseEnginer
Enginer
SERVIDOR
SERVIDOR
SQL/API
SQL/API
Banco
Bancode
deDados
Dados
Transporte
NetBios
NetBios
TCP/IP
TCP/IP IPX/SPX
IPX/SPX
SNA
SNA
SOR
Serv.
Serv.Diretrio
Diretrio
Sistema Operacional
RPC
RPC
Serv.
Serv.Diretrio
Diretrio
Mensagens
Mensagens
Segurana
Segurana
Sistema Operacional
Conexes e Contextos
Pode-se definir como conexo um caminho estabelecido entre a
aplicao e o banco de dados atravs de um usurio e sua senha.
Para cada conexo criada uma estrutura na memria do servidor de
banco preparada para receber os comandos SQL enviados pela
aplicao.
Cada conexo pode ter um ou mais contextos. Para executar um
comando SQL na aplicao necessria a criao de pelo menos um
contexto dentro da conexo.
Os comandos SQLs enviados por um contexto passam por pelo menos
duas fases: preparao e execuo. Na primeira fase verificada a
sintaxe do comando e definido o caminho de acesso que ser
utilizado pela execuo do comando (otimizao). Na segunda fase o
comando finalmente executado. Depois que a primeira fase for
completada, pode-se repetir vrias vezes a execuo da segunda
fase, otimizando o processo, j que o tempo gasto para compilar e
otimizar o comando no ser gasto novamente. Entretanto, um
mesmo contexto pode ser usado para a execuo de mais de um
Delphi Client/Server
45
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Contextos
Aplicao
Conexo
Banco
Delphi Client/Server
46
B A N C O S
D E
DA D O S
R E L A CI O N A I S
TDatabase e TDataSet
47
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Delphi Client/Server
48
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Contextos
Aplicao
Conexo
Comando
Insert
Banco
Comando
Update
Comando
Select
Cursor
Result
Set
.
.
.
.
Delphi Client/Server
49
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Transaes
Um dos recursos mais importantes fornecidos pelos bancos de dados
o controle de transao. O controle de transao permite as
aplicaes manterem a integridade lgica dos dados em um
determinado processo. Uma transao um conjunto de comandos
executados no banco de dados que devem ser aplicados
integralmente. Se um dos comandos falhar, todos os outros tm que
ser desfeitos para manter a integridade e a unicidade do processo em
execuo. Desta forma pode-se garantir a confiabilidade dos dados
armazenados no banco. Considere o seguinte exemplo: um processo
de transferncia entre contas correntes que deve debitar um valor
em uma das contas e creditar exatamente o mesmo valor em uma
outra conta. Se o processo falhar no meio e esse recurso de controle
de transao no estiver sendo utilizado, o dinheiro pode ser retirado
da primeira conta, mas no ser creditado na segunda, assim o valor
que deveria ser transferido, simplesmente desaparece da base de
dados.
Para fazer o controle de transao, so fornecidos normalmente pelos
bancos de dados trs comandos: um para iniciar a transao (begin
transaction), um para finalizar e aplicar as modificaes executadas
(commit) e outro para finalizar cancelando e desfazendo toda a
operao (rollback). Portanto, quando uma transao iniciada,
todos os comandos seguintes fazem parte de uma nica transao at
ser encontrado um comando que a finalize (commit ou rollback). Se
todos os comandos foram executados com xito, pode-se ento
disparar o comando commit para que estes sejam aplicados e se
tornem visveis para os demais usurios. Caso contrrio, se um erro
foi encontrado em algum dos comandos, pode-se disparar um
Delphi Client/Server
50
B A N C O S
D E
DA D O S
R E L A CI O N A I S
- Inicia a transao.
Commit
transao
Rollback
transao
Delphi Client/Server
51
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Projeto Exemplo
Componente
Form1
Table1
DataSource1
Grid1
Query1
DataSource2
Grid2
Propriedade
Name
DatabaseName
TableName
Active
DataSet
DataSource
DatabaseName
SQL
Request Live
DataSet
DataSource
Valor
frmTransacao
Vendas
Produto
True
Table1
DataSource1
Vendas
Select * from Produto
True
Query1
DataSource2
52
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Delphi Client/Server
53
B A N C O S
D E
DA D O S
R E L A CI O N A I S
FROM PRODUTO
54
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Concorrncia - DLSF
Pode-se definir como concorrncia o processo de disponibilizar a
mesma base de dados vrios usurios conectados simultaneamente.
Para manter a unicidade de uma transao e a confiabilidade no valor
do dado apresentado ao usurio, necessrio a utilizao de alguns
controles sobre os registros do banco de dados.
Tipos de travamentos (locks)
Para disponibilizar tal funcionalidade, o banco de dados prov
servios para bloquear um registro, de forma que outros usurios
no possam acess-lo. Alguns bancos permitem o travamento de um
nico registro, enquanto outros trabalham com unidades compatveis
com o dispositivo fsico, permitindo o travamento atravs de pginas.
Dependendo do banco, o tamanho dessas pginas pode variar (2K,
1K), podendo essas serem formadas por mais de um registro.
Portanto, quando uma pgina travada, todos os registros que ela
possui sero travados. Esse controle de atribuir e remover as travas
realizado para cada transao em cada conexo. Mesmo se duas
conexes so feitas pelo mesmo usurio, o controle de travamento
distinto, podendo assim uma das conexes bloquear registros para a
outra conexo. Deve-se ter cuidado ao se trabalhar em mais de uma
conexo para no acontecer os chamados Deadlocks, que so
travamentos causados por mais de uma conexo e que cada uma
Delphi Client/Server
55
B A N C O S
D E
DA D O S
R E L A CI O N A I S
1
Exclusiv
e
Shared
Shared
Shared
Shared
Shared
Exclusiv
e
5
Tabela de Transaes: Um exclusive lock em uma linha, exclui a possibilidade de existir outro exclusive
lock ou shared lock em uma outra coluna na mesma linha.
Nveis de isolamento
Podemos definir alguns nveis de isolamento, de acordo com a forma
que os shared locks so atribudos aos registros ou pginas. A
seguir sero mostradas as vrias formas de se trabalhar com locks
no banco de dados, independente dos nomes utilizados pelos vrios
fornecedores. Sendo possvel que alguns bancos de dados no
apresentem todas as possibilidades descritas abaixo.
Delphi Client/Server
56
B A N C O S
D E
DA D O S
R E L A CI O N A I S
57
B A N C O S
D E
DA D O S
R E L A CI O N A I S
58
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Delphi Client/Server
59
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Para se configurar o processo de Optimistic Lock no Delphi, devese utilizar a propriedade UpdateMode dos componentes DataSets:
TQuery e TTable.
Delphi Client/Server
60
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Projeto Exemplo
Delphi Client/Server
61
B A N C O S
D E
DA D O S
Componente
Form1
Database1
Query1
DataSource1
Grid1
Button1
Button2
Button3
R E L A CI O N A I S
Propriedade
Name
Alias
DatabaseName
Connected
DatabaseName
SQL
Request Live
DataSet
DataSource
Caption
Caption
Caption
Valor
frmLock
VENDAS
DBVENDAS
True
DBVENDAS
Select * from Cidade
True
Query1
DataSource1
Start Trans
Commit
Open
Tabela de Propriedades.
a transao
Delphi Client/Server
62
B A N C O S
D E
DA D O S
R E L A CI O N A I S
63
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Delphi Client/Server
64
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Delphi Client/Server
65
B A N C O S
D E
DA D O S
R E L A CI O N A I S
Projetando Aplicaes
Cliente/Servidor
Esse captulo mostra algumas tcnicas de
construo de aplicaes voltadas para o
ambiente Cliente/Servidor.
Captulo
Delphi Client/Server
66
Gerenciamento de Dados
Parte da aplicao responsvel pelo acesso e a manipulao dos
dados no servidor. Como j foi visto anteriormente, grande parte
dessa camada implementada pelo prprio servidor de banco de
dados.
Normalmente o acesso aos servios feito atravs da linguagem
SQL. Porm, tambm necessrio um conjunto de comandos para
enviar as sentenas SQLs e gerenciar a comunicao entre a
aplicao e o servidor. Esses comandos se encontram em bibliotecas
disponibilizadas pelos prprios fornecedores de banco de dados que
so instaladas em cada estao de trabalho. Alm disso cada
fabricante de ferramentas de desenvolvimento fornece tambm
mtodos e componentes capazes de simplificar e tornar mais
transparente o acesso aos diversos SGDBs.
CLIENTE
APRESENTAO
FSICO
LGICA do NEGCIO
LGICO
GERENCIAMENTO de DADOS
SERVIDOR
Fig 6.1: Camadas Fsicas e Lgicas de uma Aplicao.
Delphi Client/Server
67
Delphi Client/Server
68
Componente de ligao
Componente responsvel pela interface entre as duas camadas
acima. Sua principal caracterstica tornar os componentes visuais
independentes dos componentes de acesso, ou seja, a camada de
Apresentao da Lgica do Negcio. Esse componente o
TDataSource que fica localizado tambm na pgina Data Access da
paleta de componentes.
Delphi Client/Server
69
Construindo Aplicaes
Cliente/Servidor
Esse captulo mostra a construo de uma tela
de manuteno utilizando-se os componentes
do Delphi e como configur-los para trabalhar
com banco de dados.
Captulo
Delphi Client/Server
70
Componente
DataModule1
Propriedade
Name
Valor
DMSistVendas
Tabela de Propriedades.
Componente TDatabase
Como foi visto o componente TDatabase responsvel pela conexo
com o banco de dados. Esse componente possui algumas
propriedades que permitem a configurao dessa conexo. Pode-se
utilizar a opo Database Editor do popup menu que exibido ao se
pressionar o boto direito do mouse sobre o componente Database1.
71
72
Delphi Client/Server
73
Transaes
Como j foi visto o componente TTable possui uma forma mais
inteligente de se comportar do que o componente TQuery quando o
result set est prestes a ser destrudo atravs da realizao de um
comando commit para finalizar a transao.
O componente TQuery necessita que todas as linhas at o final da
seleo sejam trazidas para a estao cliente antes que o commit
seja executado no banco para que o usurio no perca as linhas que
ainda no foram trazidas para aplicao.
J o componente TTable simplesmente fecha o result set sem
nenhum efeito que diminua o desempenho da atualizao e se houver
a necessidade de buscar as linhas restantes da tabela um novo select
feito a partir da ltima linha trazida.
Entretanto, alguns bancos de dados permitem que o commit no
destrua os result set ou pode-se tambm utilizar conexes
separadas para a atualizao e para o result set. Desta forma no
h necessidade do componente TQuery realizar as buscas antes da
real necessidade do usurio.
Por outro lado, o componente TTable, deixa aberta uma transao
que pode, dependendo do banco de dados, estar travando alguma
pgina da tabela.
Nmero de Tabelas Acessadas
Um outro fator relevante na escolha do componente, o nmero de
tabelas que devem ser acessadas para buscar as informaes
necessrias para o usurio em uma mesma tela. At um certo
nmero de tabelas mais interessante utilizar o recurso de joins
dos bancos para trazer em um nico comando SQL, todo o conjunto
de informaes. Nesse caso um componente TQuery deveria ser
utilizado. Quando isso feito atravs de vrios componentes TTable,
as vezes necessrio trazer os dados de todas as tabelas para a
mquina cliente para que a relao entre elas possa ser feita. No
melhor caso, se filtrarmos cada tabela pelo registro selecionado na
outra, teramos que executar vrios comandos SELECTs mais simples
no servidor contra um nico comando um pouco mais complexo do
componente TQuery.
74
Componente
Query1
Propriedade
Name
DatabaseName
SQL
Valor
QProduto
DBVENDAS
Select * from produto
order by produto.prod_cd
TRUE
TRUE
Request Live
Active
Tabela de Propriedades.
Delphi Client/Server
75
Componente
Form1
Panel1
Panel2
DataSource1
DBNavigator1
DBEdit1..DBEdit4
Propriedade
Name
Caption
Align
Caption
Align
Caption
Name
DataSet
DataSource
DataSource
DataField
Valor
frmProduto
Produtos
alTop
alClient
DSMain
DMSistVendas.Qproduto
DSMain
DSMain
pro_cd..pro_estoque
Tabela de Propriedades.
76
Componente
SppedButton1
SppedButton2
SppedButton3
SppedButton4
Propriedade
Name
Name
Name
Name
Valor
btnAppend
btnDelete
btnSave
btnDiscard
Tabela de Propriedades
Delphi Client/Server
77
78
begin
TBDEDataSet(DSMain.DataSet).CancelUpdates;
end;
Componente
UpdateSQL1
QProduto
Propriedade
Name
Request Live
UpdateObject
Valor
USProduto
False
USProduto
Tabela de Propriedades
Delphi Client/Server
79
Delphi Client/Server
80
81
82
83
procedure Delete;
procedure Discard;
end;
.
Delphi Client/Server
84
then
85
Componente
Table1
Propriedade
Name
DatabaseName
TableName
Active
Valor
TUF
DBVENDAS
UF
TRUE
Tabela de Propriedades.
Componente
form1
Panel1
Panel2
DataSource1
DBNavigator
Delphi Client/Server
Propriedade
Name
Caption
Caption
Caption
Name
DataSet
DataSource
Valor
frmUF
UF
DSMain
DMSistVendas.TUF
DSMain
86
SppedButton1
SppedButton2
SppedButton3
SppedButton4
DBEdit1..DBEdit2
Name
Name
Name
Name
DataSource
DataField
btnAppend
btnDelete
btnSave
btnDiscard
DSMain
UF_SG..UF_NM
Tabela de Propriedades.
Delphi Client/Server
87
Captulo
Filtrando Registros
Esse captulo mostra algumas possibilidades
de seleo que podem ser apresentadas ao
usurio
88
Delphi Client/Server
89
S Q L
E X P L O R E R
Componente
SppedButton1
SppedButton2
Propriedade
Name
Name
Valor
btnNewForSearch
btnSearch
Tabela de Propriedades
90
S Q L
E X P L O R E R
begin
NewForSearch;
end;
procedure TfrmProduto.btnSearchClick(Sender: TObject);
begin
Search;
end;
procedure TfrmProduto.NewForSearch;
var OldOperState: TOPerState;
begin
OldOperState:=OPerState;
OperState:=opNewForSearch;
try
If Not TBDEDataSet(DSMain.DataSet).Active then begin
TQuery(DSMain.DataSet).SQL.Text:=CmdSelect + CmdSelectNull;
TBDEDataSet(DSMain.DataSet).Open;
end;
TBDEDataSet(DSMain.DataSet).Append;
finally
OperState:=OldOperState;
end;
end;
procedure TfrmProduto.SearchClick;
var OldOperState: TOPerState;
sQBE: String;
begin
ActiveControl:=Nil;
OldOperState:=OPerState;
OperState:=opSearch;
try
sQBE:=BuildQBE;
TBDEDataSet(DSMain.DataSet).close;
TQuery(DSMain.DataSet).SQL.Text:=CmdSelect+ ' where ' + sQBE +
CmdOrderBy;
TBDEDataSet(DSMain.DataSet).Open;
finally
OperState:=OldOperState;
end;
end;
Delphi Client/Server
91
S Q L
E X P L O R E R
Propriedade
Active
SQL
Valor
False
select * from Produto
Tabela de Propriedades
92
S Q L
E X P L O R E R
93
S Q L
E X P L O R E R
dsInactive
dsInsert
dsBrowse
dsEdit
Fig: 8.3: Estados do DataSet.
dsInactive
dsNewFor
Insert
dsNewFor
Search
dsBrowse
dsEdit
Fig 8.4: Nova mquina de estados.
94
S Q L
E X P L O R E R
Alm disso, uma srie de modificaes nos eventos devem ser feitas e
o cdigo completo e final da tela de produto apresentado abaixo.
Pode-se facilmente transformar a tela de Produtos em um Template
e adicionar no repositrio de objetos do Delphi. Pode-se fazer como
exerccio, a tela de cidades utilizando-se o template construdo. As
nicas dependncias da tela com a tabela de PRODUTO so as
variveis: CmdOrderBy e CmdSelectNull. Essas variveis
precisam ento ser redefinidas no evento OnCreate do Form que
herdar do template original.
unit produto;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Db, ExtCtrls, StdCtrls, Mask, DBCtrls, Buttons;
type
TOperState=(opNone,opNewForInsert,opDelete,opSave,opDiscard,opNewForSearch,op
Search);
TRecordState=(rdInactive,rdNewForSearch,rdNewForInsert,rdBrowse,rdEdit);
TfrmProduto = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
DSMain: TDataSource;
DBNavigator1: TDBNavigator;
Label1: TLabel;
DBEdit1: TDBEdit;
Label2: TLabel;
DBEdit2: TDBEdit;
Label3: TLabel;
DBEdit3: TDBEdit;
Label4: TLabel;
DBEdit4: TDBEdit;
btnAppend: TSpeedButton;
btnDelete: TSpeedButton;
btnSave: TSpeedButton;
btnDiscard: TSpeedButton;
btnNewForSearch: TSpeedButton;
btnSearch: TSpeedButton;
procedure btnAppendClick(Sender: TObject);
procedure btnDeleteClick(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
procedure btnDiscardClick(Sender: TObject);
procedure DSMainUpdateData(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnNewForSearchClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
Delphi Client/Server
95
S Q L
E X P L O R E R
96
S Q L
E X P L O R E R
Search;
end;
procedure TfrmProduto.NewForInsert;
var OldOperState: TOPerState;
begin
OldOperState:=OPerState;
OperState:=opNewForInsert;
try
If Not TBDEDataSet(DSMain.DataSet).Active then begin
TQuery(DSMain.DataSet).SQL.Text:= CmdSelect + CmdSelectNull;
TBDEDataSet(DSMain.DataSet).Open;
end;
DSMain.DataSet.Append;
SetRecordState(rdNewForInsert);
finally
OperState:=OldOperState;
end;
end;
procedure TfrmProduto.Delete;
var OldOperState: TOPerState;
begin
OldOperState:=OPerState;
OperState:=opDelete;
try
DSMain.DataSet.Delete;
TBDEDataSet(DSMain.DataSet).ApplyUpdates;
TBDEDataSet(DSMain.DataSet).CommitUpdates;
If TBDEDataSet(DSMain.DataSet).IsEmpty then begin
TBDEDataSet(DSMain.DataSet).close;
SetRecordState(rdInactive);
end else
SetRecordState(rdBrowse);
finally
OperState:=OldOperState;
end;
end;
procedure TfrmProduto.Save;
var OldOperState: TOPerState;
begin
OldOperState:=OPerState;
OperState:=opSave;
try
TBDEDataSet(DSMain.DataSet).ApplyUpdates;
TBDEDataSet(DSMain.DataSet).CommitUpdates;
SetRecordState(rdBrowse);
finally
OperState:=OldOperState;
end;
end;
procedure TfrmProduto.Discard;
var OldOperState: TOPerState;
begin
OldOperState:=OPerState;
OperState:=opDiscard;
try
If TBDEDataSet(DSMain.DataSet).UpdatesPending
then
TBDEDataSet(DSMain.DataSet).CancelUpdates
else
TBDEDataSet(DSMain.DataSet).Cancel;
If TBDEDataSet(DSMain.DataSet).IsEmpty then begin
TBDEDataSet(DSMain.DataSet).close;
SetRecordState(rdInactive);
Delphi Client/Server
97
S Q L
E X P L O R E R
end else
SetRecordState(rdBrowse);
finally
OperState:=OldOperState;
end;
end;
procedure TfrmProduto.NewForSearch;
var OldOperState: TOPerState;
begin
OldOperState:=OPerState;
OperState:=opNewForSearch;
try
If Not TBDEDataSet(DSMain.DataSet).Active then begin
TQuery(DSMain.DataSet).SQL.Text:= CmdSelect + CmdSelectNull;
TBDEDataSet(DSMain.DataSet).Open;
end;
TBDEDataSet(DSMain.DataSet).Append;
SetRecordState(rdNewForSearch);
finally
OperState:=OldOperState;
end;
end;
procedure TfrmProduto.FormDestroy(Sender: TObject);
begin
TBDEDataSet(DSMain.DataSet).close;
TQuery(DSMain.DataSet).SQL.Text:=CmdSelect;
end;
procedure TfrmProduto.Search;
var OldOperState: TOPerState;
sQBE: String;
begin
ActiveControl:=Nil;
OldOperState:=OPerState;
OperState:=opSearch;
try
sQBE:=BuildQBE;
TBDEDataSet(DSMain.DataSet).close;
TQuery(DSMain.DataSet).SQL.Text:= CmdSelect;
If sQBE <> '' then
TQuery(DSMain.DataSet).SQL.Text:=
TQuery(DSMain.DataSet).SQL.Text +' where ' + sQBE;
TQuery(DSMain.DataSet).SQL.Text:=TQuery(DSMain.DataSet).SQL.Text +
CmdOrderBy;
TBDEDataSet(DSMain.DataSet).Open;
If TBDEDataSet(DSMain.DataSet).IsEmpty then
SetRecordState(rdNewForSearch)
else
SetRecordState(rdBrowse);
finally
OperState:=OldOperState;
end;
end;
procedure TfrmProduto.DSMainUpdateData(Sender: TObject);
var ret: integer;
begin
If OperState = opNone then begin
If RecordState = rdNewForSearch then
Discard
else begin
ret:=Application.MessageBox('Deseja salvar as alteraes',
'Confirmao', MB_YESNOCANCEL + MB_ICONQUESTION );
case ret of
Delphi Client/Server
98
S Q L
E X P L O R E R
idYes: Save;
idNo: Discard;
idCancel: Abort;
end;
end;
end;
end;
procedure TfrmProduto.DSMainStateChange(Sender: TObject);
begin
If DSMain.State=dsEdit then
SetRecordState(rdEdit);
end;
function TfrmProduto.BuildQBE: String;
var sep:string;
j:integer;
begin
Sep:='';
For j:=0 to DSMain.DataSet.FieldCount-1 do
If (DSMain.DataSet.Fields[j].AsString <> '') then begin
If DSMain.DataSet.Fields[j].DataType = ftString then
Result:= Format('%s %s (%s like ''%s%s'')',
[Result,Sep,DSMain.DataSet.Fields[j].FieldName,
DSMain.DataSet.Fields[j].AsString,'%'])
else
Result:= Format('%s %s (%s = %s)',
[Result,Sep,DSMain.DataSet.Fields[j].FieldName,
DSMain.DataSet.Fields[j].AsString]);
Sep:='And';
end;
end;
procedure TfrmProduto.SetRecordState(Value: TRecordState);
begin
RecordState:=Value;
Case RecordState of
rdInactive:
begin
btnNewForSearch.Enabled:=TRUE;
btnAppend.Enabled:=TRUE;
btnSearch.Enabled:=FALSE;
btnSave.Enabled:=FALSE;
btnDiscard.Enabled:=FALSE;
btnDelete.Enabled:=FALSE;
end;
rdNewForSearch:
begin
btnNewForSearch.Enabled:=FALSE;
btnAppend.Enabled:=FALSE;
btnSearch.Enabled:=TRUE;
btnSave.Enabled:=FALSE;
btnDiscard.Enabled:=TRUE;
btnDelete.Enabled:=FALSE;
end;
rdNewForInsert:
begin
btnNewForSearch.Enabled:=FALSE;
btnAppend.Enabled:=FALSE;
btnSearch.Enabled:=FALSE;
btnSave.Enabled:=TRUE;
btnDiscard.Enabled:=TRUE;
btnDelete.Enabled:=FALSE;
end;
rdBrowse:
begin
Delphi Client/Server
99
S Q L
E X P L O R E R
btnNewForSearch.Enabled:=TRUE;
btnAppend.Enabled:=TRUE;
btnSearch.Enabled:=FALSE;
btnSave.Enabled:=FALSE;
btnDiscard.Enabled:=FALSE;
btnDelete.Enabled:=TRUE;
end;
rdEdit:
begin
btnNewForSearch.Enabled:=FALSE;
btnAppend.Enabled:=FALSE;
btnSearch.Enabled:=FALSE;
btnSave.Enabled:=TRUE;
btnDiscard.Enabled:=TRUE;
btnDelete.Enabled:=FALSE;
end;
end;
end;
end.
100
S Q L
E X P L O R E R
Componente
Query1
Table1
Query2
Propriedade
Name
DatabaseName
SQL
Valor
QConsCliente
DBVENDAS
Name
DatabaseName
TableName
Name
DatabaseName
SQL
TConsCliUF
DBVENDAS
UF
QConsCliCidade
DBVENDAS
Params
UF_SG | String
SELECT PESSOA.PES_CD ,
PESSOA.PES_NM , PESSOA.PES_TP ,
PESSOA.PES_CGCCPF
FROM CLIENTE CLIENTE , PESSOA PESSOA
WHERE ( CLIENTE.PES_CD =
PESSOA.PES_CD )
ORDER BY PESSOA.PES_NM
Tabela de Propriedades
Delphi Client/Server
101
S Q L
E X P L O R E R
Componente
form1
Panel1
Label1
Label2
Label3
Label4
Edit1
Edit2
Edit3
Edit4
Button1
button2
DataSource1
DataSource2
DataSource3
Panel2
DbGrid1
Panel3
Bitbtn1
Bitbtn2
Propriedade
Name
Caption
Align
Caption
Caption
Caption
Caption
Name
Name
Name
Name
Name
Caption
Name
Caption
Name
DataSet
Name
DataSet
Name
DataSet
Align
DataSource
Align
Kind
Kind
Valor
frmConsCliente
Clientes
alTop
Cdigo
Nome
UF
Cidade
edtCodigo
edtNome
edtUF
edtCidade
btnPesquisa
Pesquisa
btnNovo
Novo
DSMain
DMSistVendas.QConsCliente
DSUF
DMSistVendas.TConsCliUF
DSCidade
DMSistVendas.QConsCliCidade
alClient
DSMain
alBottom
bkOk
bkCancel
Tabela de Propriedades
Delphi Client/Server
102
S Q L
E X P L O R E R
Para fazermos essa consulta, iremos criar uma tela com um Grid
dentro como mostrado na figura seguinte:
Componente
Form1
DBGrid1
Propriedade
Name
BorderSyle
Align
Options
Valor
frmGrid
bsNone
alClient
[dgTitles, dgColumnResize, dgColLines,
dgTabs, dgRowSelect, dgConfirmDelete,
dgCancelOnExit]
Tabela de Propriedades
103
S Q L
E X P L O R E R
ModalResult:=mrOk;
end else if key = #27 then begin
ModalResult:=mrCancel;
end;
end;
procedure TfrmGrid.FormClose(Sender:TObject; var Action:TCloseAction);
begin
Action:=caFree;
end;
procedure TfrmGrid.DBGrid1DblClick(Sender: TObject);
begin
ModalResult:=mrOk;
end;
procedure TfrmGrid.FormShow(Sender: TObject);
var p1:TPoint;
begin
P1.x:=TForm(Owner).ActiveControl.Left;
P1.y:=(TForm(Owner).ActiveControl.Top + TForm(Owner).ActiveControl.Height);
P1:=TControl(TForm(Owner).ActiveControl.Parent).ClientToScreen(P1);
If (P1.y + 150) > Screen.Height then
P1.y:=P1.y - 150 - TForm(Owner).ActiveControl.Height;
SetBounds(P1.x,P1.y,250,150);
end;
104
S Q L
E X P L O R E R
105
S Q L
E X P L O R E R
TQuery(DSMain.DataSet).SQL.Text:=sSelect;
TQuery(DSMain.DataSet).Open;
end;
procedure TfrmConsCliente.FormCreate(Sender: TObject);
begin
CmdSelect:=TQuery(DSMain.DataSet).SQL.TExt;
DSUF.DataSet.Open;
end;
procedure TfrmConsCliente.FormDestroy(Sender: TObject);
begin
DSUF.DataSet.Close;
DSCidade.DataSet.close;
TQuery(DSMain.DataSet).SQL.TExt:=CmdSelect;
end;
procedure TfrmConsCliente.edtUFEnter(Sender: TObject);
begin
frmGrid:=TFrmGrid.Create(Self);
frmGrid.DBGrid1.DataSource:=DSUF;
If (frmGrid.ShowModal=mrOk) and (Not DSUF.DataSet.IsEmpty) then
begin
TEdit(Sender).Text:=DSUF.DataSet['UF_SG'];
edtCidade.Clear;
end;
end;
procedure TfrmConsCliente.edtCidadeEnter(Sender: TObject);
begin
DSCidade.DataSet.Close;
TQuery(DSCidade.DataSet).Params[0].value:=edtUF.Text;
DSCidade.DataSet.Open;
frmGrid:=TFrmGrid.Create(Self);
frmGrid.DBGrid1.DataSource:=DSCidade;
If (frmGrid.ShowModal=mrOk) and (Not DSCidade.DataSet.IsEmpty) then
begin
TEdit(Sender).Text:=DSCidade.DataSet['CID_NM'];
sCodCidade:=DSCidade.DataSet.FieldByName('CID_CD').AsString;
end;
end;
end.
Tela de Manuteno
Como somente um registro trazido na tela de manuteno, pode-se
explorar mais o sentido horizontal, trazendo informaes mais
detalhadas. Porm, respeitando ainda a regra de no trazer
informaes ainda no requisitadas pelo usurio. Por exemplo, pode
ser que a tela da manuteno apresente-se dividida em fichas ou
pgina. Se a informao de uma pgina tem que acessar uma outra
tabela que no seja a tabela principal, pode-se esperar o usurio
selecionar a pgina para ento buscar essas informaes no banco de
dados.
Delphi Client/Server
106
S Q L
E X P L O R E R
Componente
Query1
UpdateSQL1
Propriedade
Name
DatabaseName
CachedUpdate
UpdateObject
SQL
Valor
Qcliente
DBVENDAS
TRUE
USPessoa
Params
Name
TableName
PES_CD | Integer
USPessoa
PESSOA
SELECT PESSOA.PES_CD,
PESSOA.PES_NM,
PESSOA.PES_TP , PESSOA.PES_CGCCPF ,
PESSOA.PES_LOGRADOURO ,
PESSOA.PES_NUMERO ,
PESSOA.PES_COMPLEMENTO ,
PESSOA.PES_BAIRRO , PESSOA.CID_CD ,
PESSOA.UF_SG , PESSOA.PES_DT_NASC ,
PESSOA.CID_CD_NASC ,
PESSOA.UF_SG_NASC ,
CLIENTE.CLI_LIMITECREDITO ,
CLIENTE.CLI_DEBITO , CIDADE.CID_NM ,
UF.UF_NM
FROM PESSOA PESSOA, CLIENTE CLIENTE,
CIDADE CIDADE, UF UF
WHERE PESSOA.PES_CD =
CLIENTE.PES_CD
AND PESSOA.CID_CD = CIDADE.CID_CD
AND PESSOA.UF_SG = CIDADE.UF_SG
AND CIDADE.UF_SG = UF.UF_SG
AND PESSOA.PES_CD= :PES_CD
ORDER BY PESSOA.PES_NM
Tabela de Propriedades
Delphi Client/Server
107
S Q L
E X P L O R E R
Delphi Client/Server
108
S Q L
E X P L O R E R
Componente
Form1
Panel1
SpeedButton1
SpeedButton2
SpeedButton3
SpeedButton4
SpeedButton5
PageControl1
TabSheet1
TabSheet2
TabSheet3
DataSource1
DBControls
Propriedade
Name
Caption
Align
Name
Name
Name
Name
Name
Align
Caption
Caption
Caption
Name
DataSet
.....
Valor
frmCliente
Clientes
alTop
btnAppend
btnDelete
btnSave
btnDiscard
btnSearch
alClient
Informaes Gerais
Pessoa Fsica
Crditos
DSMain
DMSistVendas.Qcliente
.....
Tabela de Propriedades
109
S Q L
E X P L O R E R
DSMain.DataSet.close;
end;
procedure TfrmCliente.btnSaveClick(Sender: TObject);
begin
TBDEDataSet(DSMain.DataSet).ApplyUpdates;
TBDEDataSet(DSMain.DataSet).CommitUpdates;
end;
procedure TfrmCliente.btnDiscardClick(Sender: TObject);
begin
If TBDEDataSet(DSMain.DataSet).UpdatesPending
then
TBDEDataSet(DSMain.DataSet).CancelUpdates
else
TBDEDataSet(DSMain.DataSet).Cancel;
If TBDEDataSet(DSMain.DataSet).IsEmpty then begin
TBDEDataSet(DSMain.DataSet).close;
end;
end;
110
S Q L
E X P L O R E R
btnSearch.Enabled:=FALSE;
end;
dsEdit:
begin
btnAppend.Enabled:=FALSE;
btnDelete.Enabled:=FALSE;
btnSave.Enabled:=TRUE;
btnDiscard.Enabled:=TRUE;
btnSearch.Enabled:=FALSE;
end;
dsBrowse:
begin
btnAppend.Enabled:=TRUE;
btnDelete.Enabled:=TRUE;
btnSave.Enabled:=FALSE;
btnDiscard.Enabled:=FALSE;
btnSearch.Enabled:=TRUE;
end;
end;
end;
Recursos de LookUp
Existem vrias formas de fornecer para o usurio uma pesquisa em
registros de tabelas secundrias relacionadas com a tabela principal.
Esse recurso, muitas vezes chamado de lookup deve prover
implementaes para as trs fases seguintes:
Preencher e exibir uma lista ou tabela de registros para permitir a
escolha do usurio;
Ao se escolher um registro, deve-se atualizar o cdigo relacionado
na tabela principal;
Quando for selecionado um registro na tabela principal, deve-se
selecionar o registro correspondente na tabela secundria,
permitindo a exibio de alguns campos como a descrio.
Campo LookUp do Delphi
111
S Q L
E X P L O R E R
Delphi Client/Server
112
S Q L
E X P L O R E R
Outros Mtodos
113
S Q L
E X P L O R E R
end;
114
S Q L
E X P L O R E R
DSMain.DataSet['CID_CD_NASC']:=Null;
edtUFNmNasc.Text:=DSUF.DataSet['UF_NM'];
edtCidNmNasc.Text:='';
end;
end;
end;
procedure TfrmCliente.DBEdit13Enter(Sender: TObject);
begin
If DSMain.State <> dsInactive then begin
DSCidade.DataSet.Close;
TQuery(DSCidade.DataSet).Params[0].AsString:=
DSMain.DataSet.FieldByName('UF_SG_NASC').AsString;
DSCidade.DataSet.Open;
frmGrid:=TFrmGrid.Create(Self);
frmGrid.DBGrid1.DataSource:=DSCidade;
If (frmGrid.ShowModal=mrOk)
and (Not DSCidade.DataSet.IsEmpty) then begin
if DSMain.State = dsBrowse then DSMain.DataSet.Edit;
edtCidNmNasc.Text:=DSCidade.DataSet['CID_NM'];
DSMain.DataSet['CID_CD_NASC']:=DSCidade.DataSet['CID_CD'];
end;
end;
end;
Controlando Transaes
Quando se trabalha com banco de dados relacionais, pode-se utilizar
o recurso de transao para efetivar o processo como um todo ou
voltar todas as atualizaes desde o incio do processo caso algum
erro ocorra.
Em nosso exemplo, por enquanto, a manuteno de clientes est
sendo feita somente na tabela de PESSOA. Para que ele fique correto
de acordo com a lgica de negcio da aplicao, devemos atualizar
tambm a tabela de CLIENTE nas manutenes feitas pelo usurio.
Portanto, quando inserimos um registro devemos inser-lo na tabela
de PESSOA e tambm na tabela de CLIENTE. E essa insero deve
estar dentro de uma transao, para que esse processo seja feito
como um todo. Ou inserimos nas duas tabelas ou em nenhuma,
mantendo assim a integridade dos dados no banco. A mesma coisa
deve ser feita para as alteraes e excluses.
Para executarmos as operaes de insero, alterao e excluso nas
duas tabelas podemos utilizar dois componentes UpdateSQL. Assim,
no ser mais possvel utilizar a propriedade UpdateObject do
componente TQuery para definir qual dos dois componentes ser
utilizado, j que queremos utilizar os dois.
Devemos ento utilizar, ao invs dessa propriedade, um evento do
componente TQuery chamado OnUpdateRecord. Atravs desse
evento, podemos chamar cada um dos comandos fornecidos pelos
componentes UpdateSQL e fazer todas as atualizaes necessrias
nas tabelas.
Delphi Client/Server
115
S Q L
E X P L O R E R
116
S Q L
E X P L O R E R
117
S Q L
E X P L O R E R
end;
procedure TfrmCliente.btnSaveClick(Sender: TObject);
begin
DMSistVendas.Database1.StartTransaction;
try
TBDEDataSet(DSMain.DataSet).ApplyUpdates;
DMSistVendas.Database1.Commit;
TBDEDataSet(DSMain.DataSet).CommitUpdates;
EnableBtnControls;
except
DMSistVendas.Database1.Rollback;
end;
end;
Devemos
tambm
declarar
e
inicializar
a
varivel
CmdSelectQCliente no DataModule para armazenar o comando
original da query.
private
{ Private declarations }
public
{ Public declarations }
CmdSelectQCliente: String;
end;
118
S Q L
E X P L O R E R
CmdSelectQCliente:=QConsCliente.SQL.Text;
end;
Delphi Client/Server
119
S Q L
E X P L O R E R
Delphi Client/Server
120
S Q L
E X P L O R E R
Controlando Transaes
Master/Detail
Esse captulo mostra como implementar telas
que exigem um controle de transao do tipo
Master/Detail.
Captulo
Tela de Consulta
Podemos comear definindo nossa tela de consulta, que o usurio ir
utilizar para pesquisar um pedido, assim como foi feito para a tela de
clientes.
Utilizaremos mais trs componentes TQuery que sero colocados no
Data Module.
Delphi Client/Server
121
Componente
Query1
Query2
Propriedade
Name
DatabaseName
SQL
Valor
QConsPed
DBVENDAS
Name
DatabaseName
SQL
QConsPedCliente
DBVENDAS
Query3
Name
DatabaseName
SQL
QConsPedVend
DBVENDAS
SELECT PESSOA.PES_CD , PESSOA.PES_NM
FROM VENDEDOR VENDEDOR , PESSOA PESSOA
WHERE ( VENDEDOR.PES_CD = PESSOA.PES_CD )
ORDER BY PESSOA.PES_NM
Tabela de Propriedades
Delphi Client/Server
122
Componente
form1
DataSource1
DataSource2
DataSource3
Panel1
Edit...
button1
button2
Panel2
DBGrid1
Panel3
bitbtn1
bibtn2
Propriedade
Name
Caption
Name
DataSet
Name
DataSet
Name
DataSet
Align
Name
Name
Caption
Name
Caption
Align
Align
DataSource
Align
Kind
Kind
Valor
frmConsPedido
Pedidos
DSMain
DMSistVendas.QConsPed
DSCliente
DMSistVendas.QConsPedCliente
DSVend
DMSistVendas.QConsPedVend
alTop
edtNumero, edtCodCliente, edtNomeCliente,
edtCodVend, edtNomeVend
btnPesquisa
Pesquisa
btnNovo
Novo
alClient
alClient
DSMain
alBottom
bkOk
bkCancel
Tabela de Propriedades
123
Fig 9.3: Pesquisa de cliente filtrada pelas letras digitadas pelo usurio.
124
125
DSMain.DataSet.Close;
TQuery(DSMain.DataSet).SQL.TExt:=CmdSelect;
end;
procedure TfrmConsPedido.edtNomeClienteKeyUp(Sender: TObject;
var Key: Word; Shift: TShiftState);
begin
If Key = 113 then begin
DSCliente.DataSet.Close;
If edtNomeCliente.Text <> '' then
TQuery(DSCliente.DataSet).SQL[3]:=' AND PESSOA.PES_NM LIKE '''
+ edtNomeCliente.TExt + '%'''
Else
TQuery(DSCliente.DataSet).SQL[3]:='';
DSCliente.DataSet.Open;
frmGrid:=TFrmGrid.Create(Self);
frmGrid.DBGrid1.DataSource:=DSCliente;
If (frmGrid.ShowModal=mrOk) and (Not DSCliente.DataSet.IsEmpty)
then begin
TEdit(Sender).Text:=DSCliente.DataSet['PES_NM'];
edtCodCliente.Text:=DSCliente.DataSet.FieldByName('PES_CD').AsString;
end;
end;
end;
procedure TfrmConsPedido.edtNomeVendKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
If Key = 113 then begin
If Not DSVend.DataSet.Active then
DSVend.DataSet.Open;
frmGrid:=TFrmGrid.Create(Self);
frmGrid.DBGrid1.DataSource:=DSVend;
If (frmGrid.ShowModal=mrOk) and (Not DSVend.DataSet.IsEmpty)
then begin
TEdit(Sender).Text:=DSVend.DataSet['PES_NM'];
edtCodVend.Text:=DSVend.DataSet.FieldByName('PES_CD').AsString;
end;
end;
end;
end.
Tela de Manuteno
Para fazer a manuteno do pedido, vamos acrescentar no Data
Module os seguintes componentes:
Delphi Client/Server
126
Componente
Query1
Query2
UpdateSQL1
UpdateSQL2
Query3
Propriedade
Name
DatabaseName
SQL
Valor
Qpedido
DBVENDAS
UpdateObject
CachedUpdate
Name
DatabaseName
SQL
USPedido
TRUE
Qitem
DBVENDAS
UpdateObject
CachedUpdate
Name
Name
Name
DatabaseName
SQL
USItem
TRUE
USPedido
USItem
QConsPedProd
DBVENDAS
Tabela de Propriedades
127
Componente
form1
DataSource1
DataSource2
DataSource3
Panel1
SpeedButton1
SpeedButton2
SpeedButton3
SppedButton4
SpeedButton5
DBEdit...,
DBRadioGroup
DBGrid1
SpeedButton6
SpeedButton7
SpeedButton8
Delphi Client/Server
Propriedade
Name
Caption
Name
DataSet
Name
DataSet
Name
DataSet
Align
Name
Name
Name
Name
Name
DataSource
Valor
frmPedido
Pedidos
DSMain
DMSistVendas.Qpedido
DSDetail
DMSistVendas.QItem
DSCliente
DMSistVendas.QConsPedCliente
alTop
btnAppend
btnDelete
btnSave
btnDiscard
btnSearch
DSMain
DataSource
Name
Name
Name
DSDetail
btnDetailAppend
btnDetailDelete
btnDetailDiscard
128
Tabela de Propriedades
Lgica visual
Antes de comear a definir os eventos dos botes, iremos criar um
procedimento para controlar a habilitao desses botes.
procedure TfrmPedido.EnableBtnControls;
begin
Case DSMain.State of
dsInactive:
begin
btnAppend.Enabled:=TRUE;
btnDelete.Enabled:=FALSE;
btnSave.Enabled:=FALSE;
btnDiscard.Enabled:=FALSE;
btnSearch.Enabled:=TRUE;
end;
dsInsert:
begin
btnAppend.Enabled:=FALSE;
btnDelete.Enabled:=FALSE;
btnSave.Enabled:=TRUE;
btnDiscard.Enabled:=TRUE;
btnSearch.Enabled:=FALSE;
end;
dsEdit:
begin
btnAppend.Enabled:=FALSE;
btnDelete.Enabled:=FALSE;
btnSave.Enabled:=TRUE;
btnDiscard.Enabled:=TRUE;
btnSearch.Enabled:=FALSE;
end;
dsBrowse:
If TQuery(DSMain.DataSet).UpdatesPending then begin
btnAppend.Enabled:=FALSE;
btnDelete.Enabled:=FALSE;
btnSave.Enabled:=TRUE;
btnDiscard.Enabled:=TRUE;
btnSearch.Enabled:=FALSE;
end else begin
btnAppend.Enabled:=TRUE;
btnDelete.Enabled:=TRUE;
btnSave.Enabled:=FALSE;
btnDiscard.Enabled:=FALSE;
btnSearch.Enabled:=TRUE;
end;
end;
end;
Delphi Client/Server
129
130
131
usInserted:
begin
OldColor:=Canvas.Font.Color;
Canvas.Font.Color:=clGreen;
DefaultDrawColumnCell(Rect,DataCol,Column,State);
Canvas.Font.Color:=OldColor;
end;
end;
end;
132
If (frmConsPedido.ShowModal=mrOk)
and (Not (frmConsPedido.DSMain.DataSet['PED_CD'] = Null)) then
begin
TQuery(DSMain.DataSet).Params[0].value:=
frmConsPedido.DSMain.DataSet['PED_CD'];
DSMain.DataSet.Open;
DetailSearch;
end;
frmConsPedido.free;
end;
133
DSMain.DataSet.Edit;
if Not ((E is EDBEngineError) and
(EDBEngineError(E).Errors[0].NativeError = 0)) then
raise;
end;
end;
end;
134
begin
DataSet['PED_VALOR']:=0;
DataSet['PED_TIPO']:='V';
end;
Delphi Client/Server
135
136
DSMain.DataSet.FieldByName('PED_VALOR').AsFloat:=
DSMain.DataSet.FieldByName('PED_VALOR').asfloat DSDetail.DataSet.FieldByName('ITE_VALOR').asfloat;
DSDetail.DataSet.Cancel;
DSMain.DataSet.FieldByName('PED_VALOR').AsFloat:=
DSMain.DataSet.FieldByName('PED_VALOR').asfloat +
DSDetail.DataSet.FieldByName('ITE_VALOR').asfloat;
end;
end else begin
if TBDEDataSet(DSDetail.DataSet).UpdateStatus = usInserted then begin
DSMain.DataSet.FieldByName('PED_VALOR').AsFloat:=
DSMain.DataSet.FieldByName('PED_VALOR').asfloat DSDetail.DataSet.FieldByName('ITE_VALOR').asfloat;
TBDEDataSet(DSDetail.DataSet).RevertRecord;
end else if TBDEDataSet(DSDetail.DataSet).UpdateStatus = usDeleted
then begin
DSMain.DataSet.FieldByName('PED_VALOR').AsFloat:=
DSMain.DataSet.FieldByName('PED_VALOR').asfloat +
DSDetail.DataSet.FieldByName('ITE_VALOR').asfloat;
TBDEDataSet(DSDetail.DataSet).RevertRecord;
end else if TBDEDataSet(DSDetail.DataSet).UpdateStatus = usModified
then begin
DSMain.DataSet.FieldByName('PED_VALOR').AsFloat:=
DSMain.DataSet.FieldByName('PED_VALOR').asfloat DSDetail.DataSet.FieldByName('ITE_VALOR').asfloat;
TBDEDataSet(DSDetail.DataSet).RevertRecord;
DSMain.DataSet.FieldByName('PED_VALOR').AsFloat:=
DSMain.DataSet.FieldByName('PED_VALOR').asfloat +
DSDetail.DataSet.FieldByName('ITE_VALOR').asfloat;
end;
end;
end;
Regras de Negcio
Alm de inserir os registros do pedido e de seus itens, devemos
implementar algumas regras de negcio em torno dessas inseres.
Como exemplo iremos implementar duas regras de negcio: a
verificao do limite de crdito do cliente em compras a prazo e a
baixa do estoque do produto.
Essas regras de negcio devem ser implementadas dentro da
transao para que sejam efetivadas juntamente com a insero dos
registros. Para simplificar o processo iremos fazer os eventos apenas
para insero do pedido e dos itens. No iremos tratar portanto a
atualizao e excluso de itens ou do pedido.
Vamos implementar duas procedures dentro do DataModule:
public
{ Public declarations }
procedure VerificaLimiteCreditoCliente(Cliente: integer; Valor: double);
procedure UpdateEstoque(Produto: integer; Quant: integer);
end;
137
138
QItem.CommitUpdates;
end;
UpdateAction:=uaApplied;
end;
procedure TDMSistVendas.QItemUpdateRecord(DataSet: TDataSet;
UpdateKind: TUpdateKind; var UpdateAction: TUpdateAction);
begin
If UpdateKind = ukInsert then begin
QItemPED_CD.NewValue:=QPedidoPED_CD.NewValue;
UpdateEstoque(QItemPRO_CD.NewValue, QItemITE_QUANT.NewValue );
end;
USItem.Apply(UpdateKind);
UpdateAction:=uaSkip;
end;
Delphi Client/Server
139