Nenhum comentário Download


 

Delphi – Parte IV

 

Vimos no artigo anterior, a VCL (Visual Library Component) biblioteca de componentes visuais do Delphi. Claro, não pudemos ver em toda sua extensão, pois isso daria um livro, mas conhecemos os principais componentes e conheceremos outros no decorrer do curso.

 

Neste artigo conheceremos uma parte muito importante de aplicações Delphi, a conectividade com bando de dados. Atualmente, a quantidade de servidores de banco de dados é bastante grande, então você pode ficar em dúvida, será que o Delphi pode conectar ao banco de dados da minha aplicação. A resposta é quase que imediata: Sim.

 

Caso o servidor do seu banco não possui um driver para o Delphi, você pode usar outros tipos de conectividade, como ODBC, ADO etc. Ou seja, as possibilidades são muitas. Delphi inicialmente utilizava o BDE (Borland Database Engine), um núcleo da própria Borland que usava banco de dados Paradox e dBase.

 

O BDE possui vários utilitários para acessar o banco, manipular objetos e dados. Veja na Figura 1 o BDE Admin, front-end para criar conexões, criar objetos e manipular dados dos bancos de dados suportado pelo BDE.

 

 

Figura 1. BDE Admin

 

Com o tempo, devido a vários fatores, o mesmo foi descontinuado (mas possui componentes até hoje no Delphi para compatibilidade), entrando no seu lugar o dbExpress, engine mais leve e que pode usar vários tipos de servidores de bancos de dados. O dbExpress maximiza a velocidade, pois seus drivers são pequenos, rápidos e de fácil distribuição (basta um arquivo DLL).

 

Além disso, o dbExpress é cross-plataform. Em conjunto com o ClientDataSet, o dbExpress se torna uma arquitetura de alta performance e concorrência para suas aplicações, pois o ClientDataSet usa dados em memória, ou seja, você pode trabalhar desconectado. No dbExpress, cada componente tem sua responsabilidade, diferente do BDE, onde componentes responsáveis por mostrar dados, também podem conectar ao banco de dados.

 

Na Tabela 1, temos os componentes da arquitetura e suas responsabilidades.

 

Componente

Responsabilidade

SQLConnection

Sua única responsabilidade é fazer a conexão com o banco de dados

SQLDataSet

Responsável por receber o conjunto de dados e realizar as atualizações necessárias. É o que efetua os comandos SQLs no banco de dados. O conjunto de dados é unidirecional, ou seja, somente lê os dados e não pode navegar no mesmo (por isso, precisamos do ClientDataSet para navegar no conjunto de dados).

SQLQuery

Utilizado para executar comandos SQLs para retornar ou atualizar dados no banco

SQLTable

Retorna os dados da tabela indicada em suas propriedades. Esta presente mais para compatibilidade, pois seu uso não é recomendado, já que utiliza um comando select * from TABELA.

SQLStoredProc

Executa uma Stored Procedure do banco de dados.

SQLSimpleDataSet

Utiliza em conjunto um SQLDataSet e um DataSetProvider para armazenar dados em memória (em conjunto com o ClientDataSet)

SQLMonitor

Usado para interceptar mensagens do SQLConnection e o banco de dados. Você pode monitorar como as consultas estão sendo executadas.

SqlServerMethod

Presente na versão mais recente do Delphi. Serve para chamar um método no servidor DataSnap e recuperar resultados (se for o caso).

Tabela 1. Componentes do dbExpress e suas responsabilidades

Veja na Figura 2, os componentes da aba dbExpress.

 

 

Figura 2. Aba dbExpress e seus componentes

Para criarmos uma conexão para manipular um cadastro, precisamos do quarteto: SQLConnection + SQLDataSet + DataSetProvider + ClientDataSet. Vamos criar um exemplo para entendermos o funcionamento. Caso você pense que precisa de todos os componentes para cada cadastro, calma! Mostrarei vários exemplos para utilizar em aplicações cliente/server usando dbExpress.

Criando o banco de dados

Primeiramente, vamos criar o banco de dados que usaremos nos exemplos do artigo. Usarei nesse artigo o SQL Server 2008 Express, mas fique a vontade de usar outro banco de dados, pois o Delphi (dbExpress) suporta: DB2, Firebird, Informix, Interbase, SQL Server, MySQL, Oracle e conexões ODBC, como já comentado.

 

Esta bom para você essas possibilidades? Dessas opções, tem versão gratuita (SQL Server Express, Oracle Express, MySQL) ou é totalmente gratuito (Firebird).

Abra um front-end para gerenciar seu banco de dados, nesse caso, vou usar o SQL Server Management Studio. Veja o script de criação das tabelas do nosso banco na Listagem 1.

 

Listagem 1. Script para criação das tabelas do banco

CREATE TABLE CLIENTE

(

       nCdCliente   int not null primary key identity,

       sNmCliente   varchar(50) not null,

       tDtNascimento datetime,

       --limite de crédito do cliente

       nVlLimite    decimal(9,2) not null 

)

 

CREATE TABLE SETOR

(

       nCdSetor     int not null primary key identity,

       sNmSetor     varchar(30) not null

)

 

CREATE TABLE EMPREGADO

(

       nCdEmpregado int not null primary key identity,

       --empregado esta vinculado a um setor

       nCdSetor     int not null,

       sNmEmpregado varchar(50) not null,

       tDtAdmissao  datetime not null,

       --percentual de comissão do empregado

       nPcComissao  decimal(2,0) not null 

)

 

ALTER TABLE EMPREGADO ADD CONSTRAINT FK_SETOR FOREIGN KEY (nCdSetor) REFERENCES SETOR(nCdSetor)

 

CREATE TABLE PRODUTO

(

       nCdProduto   int not null primary key identity,

       sNmProduto   varchar(50) not null,

       tDtValidade  datetime not null,

       nQtEstoque   decimal(9,2)              

)

 

CREATE TABLE VENDA

(

       nCdVenda     int not null primary key identity,

       --a venda deve ter um cliente e um empregado

       nCdCliente   int not null,

       nCdEmpregado int not null,

       tDtVenda     datetime not null,

       nVlVenda     decimal(9,2) not null            

)

 

ALTER TABLE VENDA ADD CONSTRAINT FK_CLIENTE FOREIGN KEY (nCdCliente) REFERENCES CLIENTE(nCdCliente)

ALTER TABLE VENDA ADD CONSTRAINT FK_EMPREGADO FOREIGN KEY (nCdEmpregado) REFERENCES EMPREGADO(nCdEmpregado)

 

CREATE TABLE ITENS

(

       nCdVenda     int not null,

       nCdProduto   int not null,

       nVlItem             decimal(9,2) not null,

       nQtItem             decimal(9,2) not null

)

 

ALTER TABLE ITENS ADD CONSTRAINT FK_VENDA FOREIGN KEY (nCdVenda) REFERENCES VENDA(nCdVenda)

ALTER TABLE ITENS ADD CONSTRAINT FK_PRODUTO FOREIGN KEY (nCdProduto) REFERENCES PRODUTO(nCdProduto)

 

Coloquei comentários para o leitor entender alguns campos colocados nesse script. Não faz parte desse artigo ou série, explicar os tipos de campos, chaves etc do banco de dados. Acredito que o leitor já tenha algum conhecimento sobre os mesmos.

 

No decorrer da série vamos modificar ou adicionar objetos nesse banco de dados. Alguns registros foram inseridos diretamente no banco, pois não mostrarei todos os cadastros (como por exemplo SETOR, que é bastante simples).

Criando o Data Module

Para usarmos os componentes indicados anteriormente, vamos criar um Data Module. O DM é um container para adicionar os componentes de acesso a dados, o que torna a manutenção do projeto, bem mais fácil.

 

Ainda no DM, podemos colocar os métodos para as regras de negócio da nossa aplicação, ou seja, estamos deixando nosso projeto bem organizado e estruturado. Você já deve ter criado um novo projeto Delphi, então acesse File>New>Others e no item Delphi Files escolha Data Module (Figura 3).

 

 

Figura 3. Criando o Data Module

 

Dê o nome de “DM” e salve o arquivo. Podemos ter quantos DM quisermos no projeto, mas isso deve ser analisado com cuidado na hora de implementar para que aplicação não tenha problemas de performance ou fique com muitos arquivos desnecessários.

 

Agora, podemos adicionar um SQLConnection ao DM e configurar as opções para acesso ao banco de dados. Outra maneira de fazermos isso é criar uma conexão com o banco utilizando o Data Explorer.

Vamos com a segunda opção. No Data Explorer expanda o item MSSQL e veja as conexões que podem estar criadas. Clique com o botão direito no MSSQL e escolha Add New Connection. No editor, digite “DelphiTheClub”. Será criado um item filho do MSSQL com o nome digitado anteriormente.

 

Expanda o item, e veja que temos Tables, Views, Procedures, Functions etc. Ou seja, a maioria dos objetos do banco de dados para manipularmos diretamente do Delphi. Clique com o botão direito em DelphiTheClub e escolha Modify Connection.

Será aberto um editor para configurarmos a conexão com o banco de dados criado anteriormente. Veja na Figura 4 as opções que devemos digitar.

 

Nota: Lembrando apenas que a configuração de Server Name e Database Name podem mudar, de acordo com a configuração da sua máquina.

  

 

Figura 4. Configurando a conexão com o banco de dados

Caso você tenha um usuário cadastrado para conexão ao banco de dados, basta usar o User Name e Password e fazer a conexão. Outra maneira é usar o próprio Windows para isso. Acesse o botão Advanced e altere para true a opção os autenthication. Feche o editor e clique em Test Connection. Se os dados estiverem corretos, você receberá a mensagem que a conexão foi realizada com sucesso.

 

Feche o editor e de volta ao Data Explorer expanda o item Tables. Iremos visualizar as tabelas criadas anteriormente (Figura 5).

 

 

Figura 5. Conexão estabelecida com o banco de dados criado anteriormente

 

Para facilitar, clique sobre o item DelphiTheClub e arraste o mesmo para o DM. O Delphi adiciona um SQLConnection com a configuração para acesso ao banco. Para testar, altere para True a propriedade Connected. Pronto! Temos uma conexão com o banco de dados pronta no DM.

Criando o cadastro de clientes

Bom, agora, precisamos configurar os componentes do dbExpress para criarmos o primeiro cadastro da aplicação, o de clientes. Adicione no DM um SQLDataSet, um DataSetProvider e um ClientDataSet. Veja na Figura 6 os componentes dispostos no DM e seus nomes.

 

 

Figura 6. Componentes no Data Module

Agora, precisamos configurar os componentes. No dsCliente, altere a propriedade SQLConnection para “DelphiTheClub” (ou seja, o SQLConnection). Na propriedade ComandText, digite: “select nCdCliente, sNmCliente, tDtNascimento, nVlLimite from CLIENTE”.

 

Uma dica importante, nunca use o “select * from CLIENTE”, uso degrada a performance da aplicação. Outra dica é nunca usar uma consulta sem a cláusula where, ou seja, nunca trazer todos os dados em memória no ClientDataSet.

 

Nesse primeiro momento, vamos fazer isso, retornar todos os dados, mas adiante, mostrarei como usar parâmetros. Caso deseje, você pode usar um editor que o SQLDataSet tem para montar o SQL (Figura 7).

 

 

Figura 7. Editor do SQLDataSet para montar a consulta SQL

Basta dar um duplo clique no objeto ou nos campos para o Delphi adicionar os mesmos no SQL. Para testar, feche o editor e altere a propriedade Active para True. Se nenhum erro ocorrer, a consulta esta correta.

 

No DataSetProvider altere a propriedade DataSet para “dsCliente”. Essa é a única configuração (por enquanto) que precisamos fazer nesse componente. No cdsCliente altere a propriedade ProviderName para “dspCliente” e Active para True.

 

Pronto! Já estamos em condições de criar um cadastro para a tabela de clientes do banco de dados. Podemos criar um formulário e adicionar os componentes data-aware conforme visto no artigo anterior. Ou também podemos mostrar uma maneira rápida e fácil utilizando o Delphi.

 

Dê um duplo clique no cdsCliente e use a combinação de teclas Crtl + F. Note que serão adicionados os campos usados na consulta SQL, chamados TFields. Podemos, usando esse editor, fazer as formatações nos campos utilizando as propriedades EditMask, EditFormat e Currency.

 

Para que o dbExpress faça corretamente a atualizações dos campos, precisamos configurar alguns Fields. Para o campo nCdCliente, em ProvidersFlags marque como True as opções pfInWhere e pfInKey, indicando que o mesmo é o campo chave e será usado como parâmetro para a atualização.

 

Para os outros campos, que devem ser atualizados a única opção deve ser pfInUpdate, ou seja, indicamos que os campos devem ser atualizados no banco de dados. Para o campo nCdCliente precisamos configurar Required como False, para que o ClientDataSet não faça a validação desse campo que será preenchido no banco, já que o mesmo é auto-incremento.

 

Deixe o editor de Fields abertos. Abra o arquivo de formulário que será nosso cadastro de clientes. Selecione todos os campos e arraste para o formulário. Será perguntado se deseja usar a unit do DM. Escolha Sim.

 

Veja que o Delphi adiciona os componentes necessários: DataSource, DBEdit e Labels. Agora, basta adicionar um DBNavigator e vincular ao DataSource. Troque o DBEdit por um DBText para o campo nCdCliente. Pronto, execute a aplicação e cadastre os clientes que desejar (Figura 8).

 

 

Figura 8. Cadastro de cliente

Você deve, ao tentar salvar, receber a seguinte mensagem: Field value required. Isso ocorre, por que o ClientDataSet, mesmo usando dados em memória (cache), mapeia os campos do banco e o campo nCdCliente é not null.

Para contornar isso, basta preencher esse campo com algum valor. Acesse o evento OnNewRecord do cdsCliente e digite o seguinte código:

 

cdsClientenCdCliente.AsInteger := 0;

 

Faça o teste novamente e adicione alguns registros. Feche a aplicação e abra novamente. Note que os registros não estão salvos. Por que isso acontece? Por que o ClientDataSet manipula os dados em memória, ou seja, ao fechar a aplicação, os dados são descartados.

Mas como eu incluo esses dados no banco? Acesse o evento AfterPost e adicione o seguinte código:

 

cdsCliente.ApplyUpdates(0);

 

O código indica ao ClientDataSet que o mesmo deve persistir os dados no banco. Após essa alteração, insira os registros e salve. Verifique que os mesmos serão incluídos no banco.

Cadastro de empregado

O cadastro de empregado é bastante semelhante ao de cliente, mas temos a diferença que precisamos ter uma consulta para saber qual o setor do empregado para que o usuário não precise digitar o código do setor. Agora, adicione um trio de componentes para cada cadastro: empregado e setor.

 

Faça as configurações, semelhante aos do cadastro anterior. Arraste os campos para um formulário. Remova o DBEdit para o nCdSetor. Adicione um DBLookupComboBox.

Adicione também um DataSource e faça a ligação com o ClientDataSet que foi criado para trazer os dados da tabela SETOR. No DBLookupComboBox configure DataSource e DataField para o campo nCdSetor do cadastro de empregado.

 

Para exibir os setores para que o usuário possa escolher, configure ListSource (com o DataSource2), ListField (sNmSetor) e KeyField (nCdSetor). Para mostrar o formulário do cadastro de empregados ao executar a aplicação, precisamos configurar isso.

Clique com o botão direito no projeto no Project Manager e escolha Options. Acesse o item Forms e configure conforme a Figura 9.

 

 

Figura 9. Configurando a criação dos formulários

Veja que primeiro criamos o Data Module e depois os formulários da aplicação. Rode a aplicação e veja o cadastro de empregado vinculado com a pesquisa de setor (Figura 10).

 

 

Figura 10. Cadastro de empregado e consulta de setor

 

Nota: Em aplicação “real” não é interessante criar todos os formulários na inicialização do programa. O sistema ficará muito lento. Para contornar isso, basta passar os formulários para a opção Available forms e criar (utilizando menus ou botão) os mesmos em tempo de execução.

 

Com isso, vimos nessa primeira parte, dois exemplos de cadastro: um simples, com apenas alguns campos e outro com associação com outra tabela, onde precisamos ter uma consulta para que o usuário possa visualizar os dados, sem precisar saber o código.

 

No próximo artigo, vamos nos aprofundar ainda mais nessa parte de banco de dados, onde veremos características diferentes do cadastro, como parametrização, pesquisa auxiliar, usar apenas um ClientDataSet para cadastro, ao invés do trio (SQLDataSet + DataSetprovider + ClientDataSet), além de aprendermos a usar Stored Procedures.

Conclusões

Iniciamos nessa quarta parte da nossa série, uma das características do Delphi mais marcante, o trabalho com banco de dados. Vimos como usar o dbExpress para manipular dados oriundos de consultas. No próximo artigo, vamos nos aprofundar mais no dbExpress e ClientDataSet para criar cadastros mais sofisticados para nosso projeto

Um grande abraço a todos e até a próxima!