delphi 6 com oracle

238
“Ao Grande Pai Celeste, por colocar em meu caminho minha esposa e eterna companheira, Thais Sabbag Muto, e por ter confiado e entregue a nós, numa linda noite de quinta-feira, dia 1º de fevereiro de 2001, um anjinho dotado de beleza, amor e pureza inigualáveis: Lucas Sabbag Muto – nosso amado filho”

Upload: joca2008

Post on 07-Aug-2015

150 views

Category:

Documents


21 download

DESCRIPTION

Utilizando o Delphi 6 com Oracle

TRANSCRIPT

Page 1: Delphi 6 com Oracle

“Ao Grande Pai Celeste, por colocar emmeu caminho minha esposa e eterna

companheira, Thais Sabbag Muto, e por terconfiado e entregue a nós, numa linda noitede quinta-feira, dia 1º de fevereiro de 2001,

um anjinho dotado de beleza, amor e purezainigualáveis: Lucas Sabbag Muto – nosso

amado filho”

Page 2: Delphi 6 com Oracle

Agradecimentos

Ao casal Fernando e Marlene Zanatta, que sempre foram uma segunda família paramim. Obrigado por me ‘aturar’ durante toda a adolescência e juventude.

À editora Brasport, pela nova e valiosa chance.

À equipe da BufferOverflow.org, Antônio Marcelo, Felipe Cerqueira, Felipe Sarai-va e Thiago, pela eterna força que me dão no mundo LINUX.

A TODOS os meus amigos de infância, com quem convivo há pelo menos 20 anos.

”Eu, porém, vos digo que nãoresistais ao mal; mas, sequalquer um te bater na facedireita, oferece-lhe também aoutra”

Mateus 5:39

Page 3: Delphi 6 com Oracle

1

Introdução

Em função do sucesso do livro anterior, Criando Aplicações em Delphi com Bancode Dados Oracle, e do lançamento da versão 6 do Delphi, este livro procura mos-trar ao desenvolvedor Delphi, de uma forma simples e prática, todas as abas e res-pectivos componentes referentes à conexão com o banco de dados Oracle: ADO eBDE, presentes na versão anterior e a novíssima aba dbExpress, que permite umacesso mais veloz e 100% de compatibilidade com programas desenvolvidos emKylix.

O objetivo desse livro, conforme o anterior, é abordar os principais tópicos relacio-nados a essa integração e permitir ao desenvolvedor Delphi que possa escolher qualtipo de componente irá utilizar para se conectar ao banco de dados de forma queatenda suas necessidades, garantindo dessa forma, aplicações mais estáveis e comganho de performance.

O livro está dividido em cinco partes.

Na primeira parte será mostrado de forma sucinta o conceito da arquitetura clien-te/servidor.

A segunda parte é dedicada à configuração dos serviços da máquina onde está ins-talado o Delphi 6 e que irá acessar o banco de dados Oracle.

A terceira parte aborda, através de exemplos, a poderosa linguagem SQL, respon-sável pela criação, manutenção e acesso aos dados do banco de dados Oracle e outilitário SQL Plus 8.

A quarta parte do livro mostra a integração do Delphi 6 com o banco de dados Ora-cle, através das 3 abas referentes a essa conexão: BDE, ADO e dbExpress. Sãocomentados os principais componentes e as diferenças entre Tables e Queries alémde analisado o conceito de transação.

Page 4: Delphi 6 com Oracle

2 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Na quinta parte do livro são apresentados os Apêndices com dicas sobre o Delphi eo Oracle.

Portanto, o conteúdo deste livro está baseado nas principais características relacio-nadas entre o Delphi 6 e o Oracle, além de apresentar de forma resumida os princi-pais comandos da linguagem SQL.

Contatos com o autor através dos e-mails [email protected] [email protected] ou pela home-page http://www.lsminformatica.cjb.net

Page 5: Delphi 6 com Oracle

3

PARTE 1.Arquitetura Cliente/Servidor

Page 6: Delphi 6 com Oracle

5

1. Conceitos Básicos

A tecnologia cliente/servidor é uma arquitetura na qual o processamento da infor-mação é dividido em módulos ou processos distintos. Um processo é responsávelpela manutenção da informação (servidores) e outros responsáveis pela obtençãodos dados (os clientes).

Os processos cliente enviam pedidos para o processo servidor, e este por sua vezprocessa e envia os resultados dos pedidos.

Nos sistemas cliente/servidor o processamento tanto do servidor como o do clientesão equilibrados.

Geralmente, os serviços oferecidos pelos servidores dependem de processamentoespecífico, só realizados por eles. O processo cliente, por sua vez, fica livre pararealizar outros trabalhos. A interação entre os processos cliente e servidor é umatroca cooperativa, em que o cliente é o ativo e o servidor reativo, ou seja, o clienterequisita uma operação, e neste ponto o servidor processa e responde ao cliente.

��������O processo de cliente é ativo, ou seja, são eles que solicitam serviços a outros pro-gramas, os servidores. Normalmente o cliente é dedicado à sessão do usuário, co-meçando e terminando com a sessão. Um cliente pode interagir com um ou maisservidores, mas pelo menos um processo servidor é necessário. A nível de aplica-ção, o primeiro ponto a residir no cliente é a interface com o usuário. Algumastarefas a serem realizadas pelo Cliente:

� Manipulação de tela� Interpretação de menus ou comandos� Entrada e validação dos dados� Processamento de Ajuda� Recuperação de erro� Manipulação de janelas

Page 7: Delphi 6 com Oracle

6 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

� Gerenciamento de som e vídeo (em aplicações multimídia)

Gerenciando a interação com o usuário, o cliente esconde o servidor e a rede, casohouver. Para o usuário a impressão é de que a aplicação está sendo rodada com-pletamente local. Se, por acaso, o programa que interage com o usuário fizer sim-plesmente chamada de rotina, e ficar por conta do servidor todo o processamento,este certamente não é um sistema cliente/servidor.

�������Servidores são programas que respondem às solicitações por serviços compartilha-dos. Ele é um processo reativo, disparado pela chegada de pedidos de seus clientes.Geralmente, o processo servidor roda o tempo todo, oferecendo serviços a muitosclientes. Em alguns sistemas, o processo servidor em vez de responder diretamente,cria um processo escravo exclusivamente para cada pedido de cliente. O servidorbanco de dados Oracle trabalha desta forma: quando chega um pedido, ele cria umprocesso escravo dedicado a trabalhar neste pedido, deixando assim o processomestre livre para receber outros pedidos imediatamente.

Para que o servidor possa manipular os dados e prover segurança, são combinadasrotinas de gerenciamento de dados com as funções de controle encontradas nos sis-temas operacionais. Um servidor processa a informação sem interagir com outrosservidores. Os clientes que interagem com mais de um servidor têm a responsabili-dade de ativá-los quando necessário. O processamento do servidor geralmente inclui:

� acessar,� armazenar,� organizar os dados compartilhados,� atualizar dados previamente armazenados,� gerenciamento dos recursos compartilhados.

Recursos compartilhados podem ser: dados, CPU, armazenamento em disco oufita, capacidade de impressão, comunicação e até gerenciamento de vídeo e memó-ria. Um bom exemplo de servidor é o servidor de backup, que pode fornecer recur-sos de backup e recuperação em fita para várias máquinas numa rede.

As aplicações em banco de dados cliente/servidor em sua maioria são montados emcima de banco de dados SQL prontos, como o Oracle. Por exemplo, uma aplicaçãodesenvolvida com uma linguagem de 4ª geração (4GL) Delphi interagindo com dis-positivo de banco de dados Oracle é uma aplicação cliente/servidor, onde o Delphiconstitui o processo cliente e o dispositivo Oracle é o processo servidor, ambos ro-dando em nível de aplicação, caracterizando assim uma aplicação cliente/servidor.

Page 8: Delphi 6 com Oracle

Conceitos Básicos • 7

�� ��������A comunicação entre o cliente e o servidor é do estilo transacional e cooperativo. Anatureza transacional significa que o servidor envia de volta para o cliente somenteos dados relevantes. A natureza cooperativa significa que ocorre um processamentosignificativo nos dois extremos, clientes e servidor.

As primeiras aplicações em rede foram elaboradas utilizando a tecnologia de com-partilhamento de arquivos. Por exemplo, quando um usuário iniciava uma aplica-ção, o código executável da aplicação tinha que ser transmitido. Numa aplicação debanco de dados era transmitido todo o código executável do banco de dados e acada atualização, todo o banco de dados também tinha que ser transmitido, alémdisso os arquivos de índice também eram necessários para atualização. Quandotrocada por uma aplicação cliente/servidor, o executável do banco de dados perma-nece no servidor, junto com ele todos os arquivos de índices de bancos de dados,trafegando pela rede apenas os dados do pedido de gravação do cliente.

Agora vamos considerar uma aplicação baseada em host e acessada por uma redecom software de emulação de terminal. Assim, todos os toques de teclas e a maiorparte das instruções de controle de tela são transmitidas através da rede. A redetransporta todos os dados informados pelo usuário, como a escolha de um menu. Seum usuário pedir ajuda, trafegam pela rede todas as mensagens de ajuda, sendo aresponsabilidade pelo controle da tela do host.

No caso de um sistema cliente/servidor, citamos, por exemplo, uma companhiaaérea utilizando um sistema de reservas de passagens, onde temos um banco dedados compartilhado com os dados dos vôos, dados dos passageiros, tripulação,etc. O software cliente passa para o servidor somente os dados da operação comoreserva, nome do passageiro, vôo, data, todos eles já validados. O servidor rece-bendo estes dados, processa e armazena no banco de dados e envia o resultado devolta. Neste caso, o cliente é responsável pelo controle da tela e nenhuma informa-ção deste tipo trafega pela rede.

A diferença é especialmente notada em aplicações baseadas em registros, onde aincidência de informações é muito alta.

Com estes exemplos podemos ver como o sistema cliente/servidor diminui o tráfe-go na rede em relação às arquiteturas anteriores. Logicamente com isto não pode-mos dizer que uma aplicação cliente/servidor não gera tráfego de rede, mas o im-pacto de uma aplicação cliente/servidor bem elaborada é mínimo.

Uma característica dos sistemas cliente/servidor é a utilização de plataformas dehardware e softwares diferentes de um para outro. Dentro deste ‘mix’ de recursos,

Page 9: Delphi 6 com Oracle

8 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

as aplicações devem se comunicar de forma transparente. Aí entra o chamado mi-ddleware, que é todo o software existente entre os dois processos, para que eles secomuniquem. O núcleo do middleware é o sistema operacional da rede.

���������

Escalabilidade Um sistema cliente/servidor pode ser expandido verticalmentepela adição de mais recursos à máquina servidora ou aumentodo número de servidores – ou horizontalmente, pelo aumentodo número de máquinas servidoras.

Independênciade Plataformas

Os sistemas cliente/servidor não ficam presos a um ambientede software ou hardware.

MelhorPerformance

Com a força de processamento distribuída, o tempo de proces-samento é menor, e conseqüentemente o tempo de respostatambém é menor.

Fácil Acesso aosDados

Como é o processo cliente que gerencia a interface, deixandoo servidor livre para manipular os dados. Este, por sua vez,fica mais disponível.

Redução deCustosO peracionais

Troca dos sistemas grandes por sistemas com redes integradaspode ser feita com um baixo custo.

Page 10: Delphi 6 com Oracle

9

Parte II.Configurações do Cliente do Banco de

Dados Oracle

Page 11: Delphi 6 com Oracle

11

2. Serviço

Para que o Delphi possa acessar o banco de dados Oracle, através de uma conexão,deveremos configurar na estação (cliente) um serviço através do Net Easy Config.Um serviço pode ser definido como uma configuração criada no arquivo tnsnames. oraque possibilita uma conexão com o banco de dados.

������������������������������A configuração é realizada através do Net8 Easy Config1, que nos guia passo apasso para geração do serviço. A figura 2.1 nos mostra como executá-lo:

������� �

1 O Net8 Easy Config vem junto com o CD do Oracle, e deverá estar instalado na máquina que irá acessar obanco de dados.

Page 12: Delphi 6 com Oracle

12 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Uma vez executado o Net8 Easy Config, a seguinte tela deverá ser mostrada:

������� ��

Onde as opções que aparecem na janela são:

� Adicionar novo serviço – É utilizada para adicionar um novo serviço deum banco já existente;

� Modificar – É utilizada para modificar um serviço já existente;� Deletar – É utilizada para apagar um serviço;� Testar – Testa o serviço criado, efetuando uma conexão contra o banco.

�������� ����������Para criarmos um novo serviço as etapas devem ser seguidas dentro do Net8 EasyConfig conforme segue:

���!�� �"�#������������� ����������Devemos escolher a opção Adicionar novo serviço, preenchermos o campo NovoNome de Serviço com ORA_DEL e logo após clicar no botão Próximo.

Page 13: Delphi 6 com Oracle

Serviço • 13

������� �$

���!����"�#�������������!�����!������������� ��������

Ao escolhermos o nome do serviço, devemos determinar o tipo de protocolo decomunicação que será utilizado para realizarmos as conexões contra o banco dedados. O próprio Net8 Easy Config detecta os protocolos da rede instalados, e con-figura cada um para o Oracle.

Para realizar esta escolha será apresentada a tela da figura 2.4.

������� �%

Page 14: Delphi 6 com Oracle

14 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Após ter sido definido o tipo de protocolo de rede, deveremos clicar no botão Pró-ximo.

Caso haja alguma dúvida em relação ao tipo de protocolo de rede a ser utilizado,consulte o administrador da rede ou o administrador do banco de dados.

���!��$�"�#������������� �����&���������' ������!���Devemos agora especificar o nome do host, identificado por um número de IP ondeo banco de dados está localizado, assim como o número da porta.

������� �(

O número da porta que o Oracle usa como default é 1521. Dúvidas em relação aonome do host, assim como ao número da porta a serem utilizados, devem ser tira-das com o administrador da rede ou com o administrador do banco de dados.

���!��%�"�#���������� �)��������*���������������

Após a escolha do nome do host e o número da porta, devemos especificar a ins-tância do banco em que queremos nos conectar, identificada pelo SID (systemidentificator).

Geralmente o SID para o banco de dados tem o valor ORCL como default. Dúvidasem relação ao SID devem ser tiradas com o administrador do banco de dados.

Page 15: Delphi 6 com Oracle

Serviço • 15

������� �+

���!��(�"�,�������������������������Após tudo informado, o Net8 Easy Config nos dá a possibilidade de fazermos umteste do serviço instalado. Para isso, devemos clicar no botão Testar Serviço, con-forme tela apresentada na figura 2.7:

������� �-

Em seguida, devemos digitar o nome do usuário e sua respectiva senha (o Oracletem como default um usuário chamado scott, cuja senha é tiger). Após ter sidodigitado usuário/senha, deve-se clicar no botão Testar, onde uma conexão contra obanco de dados será feita, e então, aguardar a validação ou não do novo serviçocriado. Em caso positivo, a seguinte tela será apresentada:

Page 16: Delphi 6 com Oracle

16 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

������� ��

Em seguida, deve-se clicar no botão Ok, onde será finalizada a criação do novoserviço.

���!��+�"��������������������������������������

Após o preenchimento de todas as informações, o Net8 Easy Config apresentaráuma tela confirmando a criação do novo serviço, como apresentado na figura 2.9:

������� �.

Então o botão Terminar deverá ser clicado, e o novo serviço estará instalado.

Page 17: Delphi 6 com Oracle

17

Parte III.SQL

Page 18: Delphi 6 com Oracle

19

3. Conceito

O SQL é uma linguagem estruturada para manipulação de dados. É padronizadapara os bancos de dados relacionais, mas cada gerenciador pode possuir uma ex-tensão própria dessa linguagem.

A Linguagem SQL tem como grandes virtudes sua capacidade de gerenciar índices,sem a necessidade de controle individualizado de índice corrente, algo muito co-mum nas linguagens de manipulação de dados do tipo registro a registro.

Outra característica interessante na linguagem SQL é a capacidade que dispomosde cancelarmos ou gravarmos, depois de inicializadas, uma seqüência de atualiza-ções.

Page 19: Delphi 6 com Oracle

20

4. Utilizando o SQl 8 Plus

Para que possamos manipular dados, criar tabelas, índices e todas as operaçõesenvolvendo o banco de dados Oracle de uma forma direta e interativa, devemosutilizar o SQL8 Plus. A figura 4.1 mostra como executá-lo:

������% �

Uma vez executado, o SQL8 Plus exibirá uma tela de LOGIN para conexão com obanco de dados Oracle, conforme mostra a figura 4.2:

������% ��

Page 20: Delphi 6 com Oracle

Utilizando o SQL 8 Plus • 21

Os campos Nome_de_usuário, Senha deverão ser preenchidos, respectivamente,com o nome do usuário e senha de quem irá fazer o acesso1. O campoString_do_host deverá ser preenchido com o serviço criado anteriormente,ORA_DEL. Uma vez preenchidos os dados corretamente, a seguinte tela seráapresentada:

������% �$

No prompt do SQL8 Plus podemos digitar qualquer comando SQL para termosrespostas às nossas solicitações. Quando o comando ultrapassar mais de uma linha,aparecerá no editor o número das linhas digitadas. O SQL8 Plus identifica o ;(ponto-e-vírgula) como finalizador de um comando SQL, executando-o então,como nos mostra o exemplo a seguir:

SQL > SELECT * 2 FROM EMPREGADOS;

Número de linhas digitadas Finalizador de um comando SQL.

Os capítulos 6 e 7 mostrarão os principais comandos SQL.

1 Caso você não possua um login de acesso ao banco de dados, digite como usuário scott e senha tiger, ou entre emcontato com o administrador do banco de dados e solicite um.

Page 21: Delphi 6 com Oracle

22

5. Integridade de Dados

Antes de entrarmos nos conceitos da criação e manutenção de tabelas e índices,devemos primeiro entender o conceito de integridade dos dados.

Integridade de dados pode ser definida como regras criadas pelo desenvolvedor,analista ou DBA, para assegurar a consistência das informações mantidas nas ta-belas. Dessa forma, pode-se garantir que um campo numérico só receba valoresnuméricos, ou que ao incluirmos um funcionário na tabela de EMPREGADOS,somente será aceito um cargo para esse funcionário desde que esse cargo estejapreviamente cadastrado na tabela de CARGOS, conforme figura 5.1:

Tabela de funcionários Tabela de cargos

������( �

Dessa forma, esse capítulo irá abordar os principais tipos de integridade de dados,criados através de constraints, utilizados pelo banco de dados Oracle e que utiliza-remos para criação de nossas tabelas nos capítulos seguintes.

�/,���00

Como padrão, o banco de dados Oracle permite que todas as colunas aceitem valo-res nulos. Assim, a constraint NOT NULL obriga que as colunas da tabela comessa restrição possuam um valor diferente de nulo. Como exemplo podemos definirque a tabela EMPREGADOS não permita valores nulos para a coluna endereços.

Coluna com a restrição NOT NULL

NOME CARGOAndré Muto 01Thais Sabbag Muto 02

CARGO DESCRICAO01 Veterinário02 Advogado

EMPREGADO ENDERECOAlice Sabbag Rua A, 1024Ronald Muto

Page 22: Delphi 6 com Oracle

Integridade de Dados • 23

Exemplo:

CREATE TABLE EMPREGADOS (EMPREGADO VARCHAR2(5) NOT NULL, ENDERECO VARCHAR2(5) NOT NULL)

��12���3�4A restrição UNIQUE KEY obriga que o valor de uma linha de coluna ou de umconjunto de colunas que formam a chave sejam únicos. Por exemplo, em uma ta-bela de cargos, pode-se definir que a descrição dos cargos seja unívoca, pois nãopode haver mais de uma cargo com a mesma descrição.

Coluna com a restrição UNIQUE KEY

Exemplo:

CREATE TABLE CARGOS (CODCARGO VARCHAR2(3) NOT NULL, DESCRICAO VARCHAR2(25) NULL, CONSTRAINT UK_DESCRICAO UNIQUE KEY (DESCRICAO));

5617864�3�4Esse tipo de restrição define que uma coluna ou grupo de colunas farão parte dachave primária da tabela. É conveniente que cada tabela possua ao menos umachave primária. PRIMARY KEY’s, por definição, não aceitam valores nulos ouduplicados. Por exemplo, em uma tabela de empregados não devemos aceitar valo-res nulos ou duplicados na coluna matrícula.

Coluna com a restrição PRIMARY KEY

CARGO DESCRICAO01 Veterinário02 Advogado03 Veterinário

MATRÍCULA EMPREGADO00001 Sergio Dusek00001 Cesar Calil

Page 23: Delphi 6 com Oracle

24 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Exemplo:

CREATE TABLE EMPREGADOS (MATRICULA VARCHAR2(5) NOT NULL, EMPREGADO VARCHAR2(55) NULL, CONSTRAINT PK_MATRICULA PRIMARY KEY (MATRICULA));

�/6�19��3�4Essa restrição permite que seja estabelecido um relacionamento entre tabelas pormeio de colunas com o mesmo conteúdo. Assim, para cada linha da tabela-filhadeve sempre existir uma linha correspondente na tabela-mãe. Como exemplo po-demos definir que só serão cadastrados funcionários na tabela EMPREGADOS seexistirem departamentos cadastrados na tabela DEPTO.

Colunas com a restrição FOREIGN KEY

?

Exemplo:

CREATE TABLE EMPREGADO (EMPREGADO VARCHAR2(5) NOT NULL, DEPTO VARCHAR2(3) NOT NULL,

CONSTRAINT FK_DEPTO FOREIGN KEY (DEPTO) REFERENCES DEPARTAMENTO(DEPTO);

��:������#�0�,���8��8#�Essa cláusula indica que quando uma linha contendo as chaves especificadas pelarestrição FOREIGN KEY for excluída, todas as linhas da tabela-filha que se relaci-onarem com ela também o serão.

EMPREGADO DEPTOThais Sabbag 02Celia Calil 05

DEPTO DESCRICAO01 Veterinário02 Advogado

EMPREGADO DEPTOThais Sabbag 02André Muto 01

DEPTO DESCRICAO01 Veterinário02 Advogado

Page 24: Delphi 6 com Oracle

Integridade de Dados • 25

Linha excluída na tabela-mãe

Linha excluída na tabela-filha

Exemplo:

CREATE TABLE EMPREGADO (EMPREGADO VARCHAR2(5) NOT NULL, DEPTO VARCHAR2(3) NOT NULL, CONSTRAINT FK_DEPTO FOREIGN KEY (DEPTO) REFERENCES DEPARTAMENTO(DEPTO) ON DELETE CASCADE;

Page 25: Delphi 6 com Oracle

26

6. Data Definition Language (DDL)

O SQL apresenta uma série de comandos que permitem a definição dos dados,chamada de DDL (Data Definition Language), que são destinados à criação dobanco de dados, das tabelas que o compõem, além das relações existentes entre astabelas. Os próximos capítulos serão destinados, somente, à criação de tabelas eíndices, visando sua utilização com o Delphi.

,�;����Tabelas são a unidade básica de armazenamento num banco de dados1, possuindo,cada uma, um nome que as identifica, tal como as colunas que as compõem. Osdados são armazenados em linhas e colunas, que armazenam cada uma, um tipodiferente de dado (data type). A figura 6.1 nos mostra um exemplo de tabela:

EMPREGADOS Nome da tabela Nome das colunas

Tipo de dado (varchar2) Linhas������+ �

1 O Oracle permite que sejam criados os seguintes tipos de tabelas: Normais, Particionadas, Indexed-organized eClustered. Como o livro se baseia na utilização do banco de dados com o Delphi através de tabelas normais, nãoirei abordar os demais tipos.

MATRICULA NOME ENDERECO00001 Thais Sabbag Rua A00002 Patricia Dusek Rua B

Page 26: Delphi 6 com Oracle

Data Definition Language (DDL) • 27

,�!������#����Serão apresentados a seguir os principais tipos de dados para armazenamento nascolunas que compõem uma tabela:

TIPO DE DADO DESCRIÇÃO

CHAR(N) Armazena dados com tamanho fixoVARCHAR2(N) Armazena dados com tamanho variávelNUMBER(N,D) Armazena números, com tamanho e precisão

DATE Data e horaLONG Cadeia de caracteres até 2GBRAW(N), LONG RAW Dados binários

CLOB Objetos de caracteres grandesROWID Posição de um registro

BLOB Objetos binários até 4GBBFILE Ponteiro a um arquivo binário externo à base de dados

Os tipos de dados que serão utilizados para criação das nossas tabelas serão osquatro primeiros.

Por recomendação da Oracle, a partir da versão 8, deveremos sempre utilizar o tipoVARCHAR2(N), pois, em futuras versões, podem variar as sintaxes e comparaçõesde cadeia de caracteres, visando a compatibilizar o padrão SQL-3.

������Antes de começarmos este capítulo, sugiro que seja feita uma leitura prévia doApêndice B – Dicas para o Oracle, item 4 – Perigo na construção de tabelas.

Para criarmos tabelas no banco de dados, devemos utilizar o comando CREATETABLE, que tem a seguinte sintaxe:

CREATE TABLE [ esquema ].tabela (coluna tipo de dado [, coluna tipo de dado] ... [CONSTRAINT nome da constraint t ipo de constraint (coluna(s)) [REFERENCES [ esquema ].tabela (coluna(s)) ] ] ) [ TABLESPACE tablespace ] [ PCTFREE inteiro ] [PCTUSED inteiro ] [INITRANS inteiro ] [MAXTRANS inteiro ]

Page 27: Delphi 6 com Oracle

28 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

[ STORAGE cláusula de armazenamento ] [ LOGGING | NOLOGGING ] [ CACHE | NOCACHE ]

Onde:

esquema – identifica o dono da tabela;tabela – identifica o nome da tabela;coluna – identifica o nome da coluna;tipo de dado – tipo de dado da coluna;nome da constraint – nome que identifica a constraint;tipo de constraint – tipo de integridade de dados;coluna(s) – colunas da tabela que irão fazer parte da constraint.

As demais cláusulas são comentadas no Apêndice B – Dicas para o Oracle.

Exemplo: Nome da tabelaCREATE TABLE EMPREGADOS (MATRICULA VARCHAR2(5) Tamanho

NOME VARCHAR2(50) Tipo de dado (data type)CONSTRAINT PK_MATRICULA PRIMARY KEY (MATRICULA));

Nome da coluna Nome da constraint Coluna da tabela Tipo de constraint

8�������Para alterarmos uma tabela, devemos usar a seguinte sintaxe:

ALTER TABLE [ esquema ].tabela instrução (coluna tipo de dado [, coluna tipo de dado] ...

Onde:

esquema – identifica o dono da tabela;tabela – identifica o nome da tabela;comando – identifica o tipo de comando a ser executado, que pode ser:

- MODIFY – modifica o tipo de dado de uma coluna;- DROP – remove uma coluna;- ADD – inclui uma coluna nova.

coluna – identifica o nome da coluna;tipo de dado – tipo de dado da coluna;

Page 28: Delphi 6 com Oracle

Data Definition Language (DDL) • 29

Exemplo (alterando o tipo de dado e o tamanho):

Nome da tabela

ALTER TABLE CARGOS Tamanho

MODIFY("CODCARGO" CHAR(15));

Comando Coluna Tipo de dado

Exemplo (incluindo uma coluna):

Nome da tabela

ALTER TABLE CARGOS Tamanho

ADD("TESTE" VARCHAR2(10));

Comando Coluna Tipo de dado

6� ����Para removermos uma tabela criada, devemos obedecer a seguinte sintaxe:

DROP TABLE [ esquema ].tabela[CASCADE CONSTRAINTS];

Onde:

esquema – identifica o dono da tabela;tabela – identifica o nome da tabela;cascade constraints – esta opção é necessária se for uma tabela-mãe num relacio-namento FOREIGN KEY.

Exemplo:

DROP TABLE EMPREGADOS;

Nome da tabela

Page 29: Delphi 6 com Oracle

30 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

��������������������

Para adicionarmos uma constraint em uma tabela já criada, devemos usar a sintaxe:

ALTER TABLE [ esquema ].tabelaADD CONSTRAINT nome da constraint t ipo de constraint (coluna(s)) [REFERENCES [ esquema ].tabela (coluna(s)) ];

Onde:

esquema – identifica o dono da tabela;tabela – identifica o nome da tabela;nome da constraint – nome que identifica a constraint;tipo de constraint – tipo de integridade de dados;coluna(s) – colunas da tabela que irão fazer parte da constraint.

Exemplo:

Nome da tabela Tipo de constraint Coluna da tabela

ALTER TABLE EMPXCARGO ADD CONSTRAINT FK_CODCARGO FOREIGN KEY (CODCARGO) REFERENCES CARGOS2(CODCARGO) ON DELETE CASCADE,

Nome da constraint

Tabela que a constraint referencia

Cláusula

Coluna da tabela

6� ������������������

Para removermos uma constraint, devemos usar a sintaxe:

ALTER TABLE [ esquema ].tabelaDROP CONSTRAINT nome da constraint;

Onde:

esquema – identifica o dono da tabela;tabela – identifica o nome da tabela;nome da constraint – nome que identifica a constraint.

Page 30: Delphi 6 com Oracle

Data Definition Language (DDL) • 31

Exemplo:

Nome da tabela

ALTER TABLE EMPXCARGODROP CONSTRAINT FK_CODCARGO;

Nome da constraint

<������Índices são estruturas de dados que contêm ponteiros ordenados para os dados,permitindo dessa forma, um acesso direto às linhas de uma tabela.

Índices não apenas otimizam a recuperação de dados em uma tabela, aumentam avelocidade de atualizações e exclusões, em função do banco de dados Oracle en-contrar a linha antes de atualizá-la ou excluí-la.

Podemos criar um número ilimitado de índices, só que, antes de criá-los, devemosconsiderar os reais benefícios e vantagens obtidos, uma vez que, atualizada ou inse-rida uma linha na tabela, todos os índices definidos serão atualizados dinami-camente, consumindo tempo e reduzindo a perfomance do banco de dados.

As situações descritas a seguir nos levariam a criar índices:

� Tabelas grandes que retornam, na consulta, menos de 25% das linhas;� A coluna contém uma extensa cadeia de valores;� Colunas usadas freqüentemente numa cláusula WHERE e JOIN.

Em contrapartida, nas situações a seguir, não haveria a necessidade da criação deíndices:

� A tabela é alterada freqüentemente;� Colunas que possuam muitos valores NULL;� Tabelas com pequeno número de linhas.

O banco de dados Oracle cria automaticamente índices onde houverem constraintsdo tipo UNIQUE KEY e PRIMARY KEY.

������Para criarmos índices no banco de dados, devemos utilizar o comando CREATEINDEX, que possui a seguinte sintaxe:

CREATE [UNIQUE] INDEX [ esquema ].índiceON [ esquema ].tabela

Page 31: Delphi 6 com Oracle

32 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

(coluna [ASC | DESC], [coluna [ASC | DESC] ],...)[ TABLESPACE tablespace ]

[ PCTFREE inteiro ][PCTUSED inteiro ][INITRANS inteiro ][MAXTRANS inteiro ][ STORAGE cláusula de armazenamento ][ LOGGING | NOLOGGING ][ NOSORT ]

Onde:

esquema – identifica o dono da tabela/índice;índice – identifica o nome do índice;tabela – identifica o nome da tabela;coluna – identifica o nome da coluna.

As demais cláusulas são comentadas no Apêndice B – Dicas para o Oracle.

Exemplo:

Nome do índice

CREATE INDEX I_EMPREGADON EMPREGADOS (MATRICULA);

Coluna da tabela

Tabela

8�������

Em índices só os parâmetros de armazenamento podem ser modificados. Para alte-rar as colunas que formam um índice, é necessário removê-lo, e então, recriá-lo.

Exemplo: Nome do índice

ALTER INDEX I_EMPREGADSTORAGE (NEXT 400K MAXEXTENTS 110);

6� ����

Para removermos um índice, devemos utilizar a sintaxe:

Page 32: Delphi 6 com Oracle

Data Definition Language (DDL) • 33

DROP INDEX [ esquema ].índice;

Onde:

esquema – identifica o dono da tabela;índice – identifica o nome do índice.

Exemplo:

DROP INDEX I_EMPREGAD;

Nome do índice

6��������� �=�����Para recriarmos um índice, devemos utilizar a sintaxe:

ALTER INDEX [ esquema ].índice REBUILD;

Onde:

esquema – identifica o dono da tabela;índice – identifica o nome do índice.

Exemplo:

ALTER INDEX I_EMPREGAD REBUILD;

Nome do índice

Page 33: Delphi 6 com Oracle

34

7. Data Manipulation Language (DML) eData Control Language (DCL)

#70A DML, linguagem de manipulação de dados, é utilizada para recuperar ou mani-pular dados em uma ou mais tabelas.

A seguir estão relacionados os principais comandos da classe DML:

CO MANDO FUNÇÃO

SELECT Responsável por recuperar os dados de uma ou mais tabelas.Principal comando da linguagem.

INSERT Responsável por inserir uma linha na tabela.

DELETE Responsável por deletar uma os mais linhas na tabela.

UPDATE Responsável por atualizar uma os mais linhas na tabela.

#�0A DCL, linguagem de controle de dados, é utilizada para confirmar ou desfazertransações pendentes no banco de dados Oracle.

A seguir estão relacionados os principais comandos da classe DCL:

CO MANDO FUNÇÃO

CO MMIT Responsável por confirmar as transações pendentes no banco.

RO LLBACK Responsável por cancelar as transações pendentes no banco.

Page 34: Delphi 6 com Oracle

Data Manipulation Language (DML) e Data Control Language (DCL) • 35

1�������>�8!���������8��������#������ � ��,�;���Para que possamos ilustrar a utilização dos comandos DML, iremos trabalhar,como exemplo, com as tabelas a seguir:

FUNCIO NÁRIOS DEPARTAMENTOCAMPO TIPO TAMANHO CAMPO TIPO TAMANHOMATRICULA VARCHAR2 03 DEPTO VARCHAR2 03NOME VARCHAR2 50 DESCRICAO VARCHAR2 50SALARIO NUMBER 6,2DEPTO VARCHAR2 03

1��������#����O comando que insere dados em uma tabela é o INSERT, sendo sua sintaxe:

INSERT INTO [esquema].tabela [(coluna(s))]VALUES (valor(es)).

Onde:

esquema – identifica o dono da tabela;tabela – identifica o nome da tabela;coluna – identifica as colunas da tabela;valor – identifica os valores a serem inseridos na tabela.

Tomando como exemplo a tabela de funcionários, para inserirmos uma nova linha,devemos digitar a seguinte linha de comando:

INSERT INTO FUNCIONARIOSVALUES (‘001’,’THAIS MARTINS SABBAG’, 5000.25,’001’);

1 linha processada.

As colunas da tabela não foram discriminadas, uma vez que estamos inserindo todosos dados referentes a elas. Se desejarmos inserir dados em uma só coluna e utilizar-mos o comando a seguir, o banco de dados Oracle nos retorna um código de erro.

INSERT INTO FUNCIONARIOS VALUES (‘001’);

ORA-00947: nao ha valores suficientes

Page 35: Delphi 6 com Oracle

36 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Para que a inclusão seja feita corretamente, devemos utilizar:

INSERT INTO FUNCIONARIOS (MATRICULA) VALUES (‘001’);

1 linha processada.

Os dados a serem incluídos devem ser do mesmo tipo que o das colunas da tabela.

INSERT INTO FUNCIONARIOS VALUES (‘001’,’THAIS MARTINS SABBAG’, 5000.12,’001’);

String String Numérico String

8!�������#����O comando responsável por apagar linhas de uma tabela é o DELETE, sendo suasintaxe:

DELETE FROM [esquema].tabelaWHERE condição

Onde:

esquema – identifica o dono da tabela;tabela – identifica o nome da tabela;condição – identifica a linha ou linhas a serem excluídas.

Tomando como exemplo a tabela DEPARTAMENTOS, para apagar um departa-mento cujo código é ‘002’:

Exemplo1:

DELETE FROM DEPARTAMENTOSWHERE DEPTO=002ouDELETE FROM DEPARTAMENTOSWHERE DEPTO=’002’

1 linha processada.

Page 36: Delphi 6 com Oracle

Data Manipulation Language (DML) e Data Control Language (DCL) • 37

Exemplo2:

DELETE FROM FUNCIONARIOSWHERE DEPTO=002 AND SALARIO > 1500ouDELETE FROM FUNCIONARIOSWHERE DEPTO=’002’ AND SALARIO > 1500

8��������#����O comando responsável por alterar linhas de uma tabela é o UPDATE, sendo suasintaxe:

UPDATE [esquema].tabelaSET coluna = valorWHERE condição

Onde:

esquema – identifica o dono da tabela;tabela – identifica o nome da tabela;coluna – é o nome da coluna a ser atualizado;valor – novo valor para a coluna;condição – identifica a condição para atualização.

Tomando como exemplo a tabela FUNCIONARIOS, para alterar o nome do funci-onário para ‘ANDRE ANEXAMANDRO’ onde a matrícula for igual a ‘005’:

UPDATE FUNCIONARIOSSET NOME=’PLINIO ALVISE MUTO’WHERE MATRICULA=’005’

1 linha processada.

O novo valor deve ser do mesmo tipo que o da coluna da tabela a ser atualizada.

Exemplo 1:

UPDATE FUNCIONARIOSSET NOME=’PLINIO ALVISE MUTO’WHERE MATRICULA=’005’ String

ouUPDATE FUNCIONARIOSSET NOME=’PLINIO ALVISE MUTO’WHERE MATRICULA=005 String

Page 37: Delphi 6 com Oracle

38 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Exemplo 2:

UPDATE FUNCIONARIOSSET NOME=’PLINIO ALVISE MUTO’, DEPTO = ‘001’WHERE MATRICULA=’005’ StringouUPDATE FUNCIONARIOSSET NOME=’PLINIO ALVISE MUTO’, DEPTO = ‘001’WHERE MATRICULA=005 String

�����������#����Nos exemplos criados anteriormente os dado s não foram transferidosdiretamente e as manipulações feitas nas tabelas afetam primeiramente o‘buffer’ do banco de dados Oracle. Somente o usuário que realizou tais ope-rações pode visualizá-las, os demais continuam a enxergar a imagem antiga dastabelas, não conseguindo alterar as linhas afetadas, que estão travadas. Obser-vemos o exemplo seguinte:

O usuário Sérgio Dusek resolve atualizar os dados da tabela FUNCIONARIOS.

�������������������������5#8,�

MATRÍCULA NO ME SALARIO DEPTO001 ANDRE ANEXAMANDRO 1500 001002 MARILEA DUSEK 1300 001003 FABIO MUTO 1900 001

COMANDO SQL:UPDATE FUNCIONARIOSSET NOME=’RONALD MUTO’WHERE MATRICULA=’003’

��������������!?�����5#8,�

MATRÍCULA NO ME SALARIO DEPTO001 ANDRE ANEXAMANDRO 1500 001002 MARILEA DUSEK 1300 001003 RONALD MUTO 1900 001

Page 38: Delphi 6 com Oracle

Data Manipulation Language (DML) e Data Control Language (DCL) • 39

Ao mesmo tempo, o usuário Rafael Zanatta resolve fazer uma consulta na mesmatabela. O resultado visualizado é o mostrado a seguir, uma vez que só Sérgio Dusekenxerga os novos dados da tabela, pois as mudanças, como já foi dito, estão pen-dentes no banco e só são acessíveis ao usuário que as efetuou.

MATRÍCULA NO ME SALARIO DEPTO001 ANDRE ANEXAMANDRO 1500 001002 MARILEA DUSEK 1300 001003 FABIO MUTO 1900 001

,����� ��������7��������5���������� 5� �������Para que todas as mudanças efetuadas nas linhas de uma tabela possam ser perma-nentes e dessa forma serem consultadas e/ou atualizadas por todos os usuários,espelhando a realidade do banco de dados, utilizaremos o comando COMMIT.

O comando COMMIT transfere todas as informações pendentes da instância dobanco em memória para os discos físicos.

No exemplo anterior, para que as alterações reflitam em todo o banco de dados, ousuário Sérgio Dusek deve digitar o comando COMMIT.

��������������7��������5��������Para cancelarmos atualizações realizadas em linhas de uma tabela que estejampendentes no banco de dados, retornando ao estado inicial antes da modificação,utilizaremos o comando ROLLBACK.

O comando ROLLBACK desfaz todas as alterações pendentes na instância do ban-co em memória.

Utilizando ainda o exemplo anterior, se o usuário Sérgio Dusek quisesse cancelaras alterações efetuadas, o comando ROLLBACK deveria ser digitado.

�������������#��������� ��,�;���Para extrairmos informações de nossas tabelas do banco de dados, utilizaremos oSELECT, que é o principal comando da linguagem DML.

Utilizando o comando SELECT, poderemos efetuar as seguintes operações:

Page 39: Delphi 6 com Oracle

40 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

� Seleções – permite retornar linhas de uma tabela;� Projeções – permite retornar as colunas de uma tabela;� Joins – permite concatenar diferentes tabelas através de uma coluna co-

mum entre elas.

Para utilizarmos o comando SELECT, devemos utilizar a sintaxe básica:

SELECT [DISTINCT] {* | coluna, [alias da coluna], ...}FROM [esquema].tabela [alias da tabela];[WHERE condição][GROUP BY expressão1 [,expressão] ... ][ORDER BY {expressão2 | posição} [ASC,DESC] [,{expressão | posição} [ASC,DESC]];

Onde:

DISTINCT – identifica que os dados da tabela não serão duplicados;* – exibe todas as colunas da tabela;Coluna – identifica a coluna da tabela que será exibida;Alias da coluna – identifica um alias para coluna;Esquema – identifica o dono da tabela;Tabela – identifica o nome da tabela:Condição – identifica a condição de join;Expressão1 – identifica um alias para coluna;Expressão2 – identifica o ordenamento pelo número da coluna;Posição – identifica o ordenamento pelo número da coluna;ASC,DESC – identifica se os dados serão exibidos em ordem ASCendente ouDESCendente, sendo o padrão ASCendente;

Exemplo:

Colunas que serão exibidas

SELECT matricula, salario, depto

FROM FUNCIONARIOS Tabela

WHERE salario >= 1500 Condição

ORDER BY 3;

Posição (ordenado pela 3ª coluna)

A seguir serão mostrados exemplos da utilização do comando SQL, utilizando astabelas criadas no item “Inserindo, Apagando e Alterando Dados em uma Tabela”,que terão o seguinte conteúdo:

Page 40: Delphi 6 com Oracle

Data Manipulation Language (DML) e Data Control Language (DCL) • 41

FUNCIO NÁRIOS

MATRICULA NO ME SALARIO CARGOS DEPTO

001 RONALD MUTO 1500 002 001002 THAIS SABBAG MUTO 3000 001 002003 SERGIO DUSEK 2000 004 001004 ANDRE MUTO 2350 003 002005 RAFAEL ZANATTA 1930 002 001006 PATRICIA DUSEK 2450 001 002007 ARLETTE DUSEK 3900 005 001

DEPARTAMENTO

DEPTO DESCRICAO001 INFORMATICA002 JURIDICO

CARGOS

DEPTO DESCRICAO001 ADVOGADO002 SUPERVISOR003 VETERINARIO004 GERENTE005 GERENTE GERAL

Exemplo 1 – Selecionando todos os dados da tabela DEPTO

SELECT * FROM DEPTO;

DEP DESCRICAO --- ------------------------------------------------ 001 INFORMATICA 002 JURIDICO

Exemplo 2 – Selecionando o funcionário cuja matrícula é igual a ‘002’

SELECT * FROM FUNCIONARIO WHERE MATRICULA=’002’;

MAT NOME SALARIO DEP --- --------------------------------- ---------- --- 002 THAIS SABBAG MUTO 3000 002

Page 41: Delphi 6 com Oracle

42 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Exemplo 3 – Selecionando o nome e o salário dos funcionários que trabalham nodepartamento ‘001’, ordenados por nome.

SELECT NOME, SALARIO FROM FUNCIONARIO WHERE DEPTO=’001’ ORDER BY NOME;

NOME SALARIO ----------------------------------------- ---------- ARLETTE DUSEK 2900 RAFAEL ZANATTA 1930 RONALD MUTO 1500 SERGIO DUSEK 2000

Exemplo 4 – Selecionando o nome e o salário dos funcionários, cujo cargo é o‘007’.

SELECT NOME, SALARIO FROM FUNCIONARIO WHERE CARGO=’007’;

NOME SALARIO ----------------------------------------- ---------- ARLETTE DUSEK 3900

/!������O banco de dados Oracle é compatível com a maioria dos operadores encontradosnas diversas linguagens de programação. Atuam sobre os elementos que serão ana-lisados pelo operador, os operandos.

Quando mais de um tipo de operador estiver presente em uma linha, eles serãoavaliados segundo a ordem de precedência descrita a seguir:

1. Operadores unários2. Divisão e multiplicação: /, *3. Adição e subtração: +, –4. Operadores de comparação5. Operador NOT6. Operador AND7. Operador OR

A seguir serão mostrados os tipos de operadores suportados pelo banco de dados Oracle:

Page 42: Delphi 6 com Oracle

Data Manipulation Language (DML) e Data Control Language (DCL) • 43

8�� @�����Operam sobre os operandos numéricos.

� Multiplicação � *� Divisão � /� Subtração � -� Adição � +

��������Manipulam strings.

� Concatenação � ||

�� !������ Igualdade � =� Desigualdade � !=� Maior que � >� Menor que � <� Maior ou igual � >=� Menor ou igual � <=� Nulo � IS NULL� Limites � BETWEEN ... AND ..� Lista de valores � IN� Máscara � LIKE

0?�����Manipulam expressões de comparação.

� NOT� AND� OR

��,Combinam o resultado de duas consultas em uma única.

� UNION � Retorna as linhas selecionadas por qualquer das consultas� INTERSECT � Retorna as linhas selecionadas pelas duas consultas� MINUS � Retorna as linhas selecionadas pela primeira, mas não pela

segunda coluna

Page 43: Delphi 6 com Oracle

44 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Exemplo 1 – Selecionando o nome, salário e o departamento dos funcionários quetrabalham no departamento ‘001’ com salário maior ou igual a 1930, ordenados pornome.

SELECT NOME, SALARIO, DEPTO FROM FUNCIONARIO WHERE SALARIO >= 1930 AND DEPTO = ‘001’ ORDER BY 1; NOME SALARIO DEP ------------------------------------- ---------- --- ARLETTE DUSEK 3900 001 RAFAEL ZANATTA 1930 001 SERGIO DUSEK 2000 001

Exemplo 2 – Selecionando o nome, salário e salário aumentado de 10%, para todosos funcionários cujo salário seja menor que 2100, ordenados por nome.

SELECT NOME, SALARIO, SALARIO*1.10 FROM FUNCIONARIO WHERE SALARIO < 2100 ORDER BY 1;

NOME SALARIO SALARIO*1.--------------------------------- ---------- ----------RAFAEL ZANATTA 1930 212,30RONALD MUTO 1500 1650SERGIO DUSEK 2000 2200

����A��Uma função SQL é uma rotina que realiza uma operação específica e retorna umresultado, podendo receber argumentos que serão utilizados no processamento.

As funções SQL são divididas em funções de linha simples ou escalares e funçõesde grupo ou agregadas.

����A������0��&�Uma função de linha ou escalar retorna o resultado para cada linha de uma ta-bela. Estão relacionadas a seguir as principais funções de linha do banco dedado s Oracle.

Page 44: Delphi 6 com Oracle

Data Manipulation Language (DML) e Data Control Language (DCL) • 45

�������

LOWER(coluna/expressão) �

UPPER(coluna/expressão) �

INITCAP(coluna/expressão) �

CONCAT(coluna1/expressão1, coluna2/expressão2) �

SUBSTR(coluna/expressão,m,[n]) �

LENGTH(coluna/expressão) �

INSTR(coluna/expressão,m) �

Converte caracteres para minúsculo.Converte caracteres para maiúsculo.Converte para maiúscula a primeiraletra de uma string.

Concatena duas strings.Retorna uma substring de uma string,iniciando da posição m, com n posições.Retorna o tamanho de uma string.Retorna a posição de um caractere den-tro de uma string.

�� @����

ROUND(coluna/expressão,m) �

MOD(m,n) �

TRUNC(coluna/expressão,m) �

Arredonda uma coluna/expressão para‘n’ casas decimais.Retorna o resulta de m dividido por n.Trunca uma coluna/expressão para ‘m’decimais.

#���

MONTHS_BETWEEN(data1,data2)�ADD_MONTHS(data,m) �

NEXT_DAY(date,’char’) �

LAST_DAY(date,’char’) �

ROUND(date[,formato]) �

TRUNC(date[,formato]) �

Número de meses entre duas datas.Adiciona ‘m’ meses para uma data.Encontra o próximo dia de uma deter-minada data.Encontra o dia anterior de uma deter-minada data.Arredonda uma data.Trunca uma data.

�������

TO_CHAR(number/date[,‘fmt’] �

TO_NUMBER(char) �

TO_DATE(char[,fmt]) �

Converte uma data/número para VAR-CHAR2.Converte uma string para um número.Converte uma string representado datapara uma data.

Page 45: Delphi 6 com Oracle

46 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Exemplo 1 – Selecionando o nome, exibido em letras minúsculas, e o salário di-minuído de 20%, sem casas decimais, para todos os funcionários que trabalham nodepartamento ‘001’ e que iniciam com a letra ‘R’.

SELECT UPPER(NOME), ROUND(SALARIO-(SALARIO*0.20),0) FROM FUNCIONARIO WHERE DEPTO = '001' AND NOME LIKE ‘R%’;

LOWER(NOME) ROUND(SALA ----------------------------------------- ---------- ronald muto 1200 rafael zanatta 1540

Exemplo 2 – Exibir as três primeiras letras dos fucionários que possuem o cargoidentificado por ‘001’.

SELECT SUBSTR(NOME,1,3) FROM FUNCIONARIO WHERE CARGO= '001';

SUB --- THA PAT

����A������9�!�Uma função de grupo ou agregada retorna um único resultado para um grupo delinhas de uma tabela. Estão relacionadas a seguir as principais funções de grupo dobanco de dados Oracle.

AVG([DISTINCT/ALL],n) �

COUNT({* | [DISTINC|ALL] expressão}) �

MAX([DISTINCT/ALL],expressão) �

MIN([DISTINCT/ALL],expressão) �

SUM([DISTINCT/ALL],m) �

Média.Conta o número de linhas deuma tabela através da expres-são.Obtém o valor máximo de umatabela através da expressão.Obtém o valor mínimo de umatabela através da expressão.Soma valores de uma tabela.

Page 46: Delphi 6 com Oracle

Data Manipulation Language (DML) e Data Control Language (DCL) • 47

Exemplo 1 – Selecionando o número de funcionários cujo cargo é identificado pelocódigo ‘001’.

SELECT COUNT(*) FROM FUNCIONARIO WHERE CARGO = '001';

COUNT(*) ---------- 2

Exemplo 2 – Selecionando a média salarial, sem casas decimais, o maior e o menorsalário e a soma dos salários do departamento ‘001’.

SELECT ROUND(AVG(SALARIO),0),MAX(SALARIO),MIN(SALARIO), SUM(SALARIO) FROM FUNC WHERE DEPTO = '001';

ROUND(AVG( MAX(SALARI MIN(SALARI SUM(SALARI ---------- ---------- ---------- ---------- 2080 2900 1500 8330

Todas as funções anteriores foram tratadas na tabela como um único grupo de in-formações. Para dividirmos a tabela em pequenos grupos de informações devemosutilizar a cláusula GROUP BY.

Exemplo 1 – Selecionando a média salarial dos departamentos, sem casas deci-mais.

SELECT DEPTO, ROUND(AVG(SALARIO),0) FROM FUNCIONARIO GROUP BY DEPTO;

DEP ROUND(AVG( --- ---------- 001 2080 002 2600

NO TA: Podemos utilizar funções de linha e de grupo simultaneamente em nossocomando SELECT como nos mostra o exemplo anterior. Não podemos utilizar acláusula WHERE para restringir grupos.

Page 47: Delphi 6 com Oracle

48 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Exemplo 2 – Selecionando a média salarial maior que 1800 dos departamentos.

SELECT DEPTO, AVG(SALARIO) FROM FUNCIONARIO WHERE AVG(SALARIO) > 1800 GROUP BY DEPTO;

ORA-00934: a função de grupo não é permitida aqui.

�������������#��������7'���!����,�;����Nos exemplos mostrados anteriormente, as operações foram feitas somente emuma tabela. O comando SELECT permite que façamos concatenações em diversastabelas, bastando para isso que a cláusula WHERE seja satisfeita.

Caso a cláusula WHERE não seja, ou seja mal especificada, teremos o produtocartesiano das tabelas como resultado.

#���������8�������!���,�;����Para facilitar o uso e evitar referências ambíguas a colunas com mesmo nome nasdiversas tabelas utilizadas no SELECT, usaremos o recurso de alias, que é um‘apelido’ criado para tabela que lhe serve de referência.

Exemplo:

Colunas de diferentes tabelas referenciadas pelos seus respectivos alias

SELECT F.NOME, D.DESCRICAO

Tabelas

FROM FUNCIONARIO F, DEPTO D

Alias criados para as tabelas WHERE F.DEPTO = D.DEPTO;

Condição de união das tabelas

Exemplo 1 – Selecionando o nome do departamento e sua respectiva média salarial.

SELECT D.DESCRICAO,AVG(F.SALARIO) FROM FUNCIONARIO F, DEPTO D WHERE F.DEPTO = D.DEPTO GROUP BY D.DESCRICAO;

Page 48: Delphi 6 com Oracle

Data Manipulation Language (DML) e Data Control Language (DCL) • 49

DESCRICAO AVG(F.SALA ------------------------- ---------- INFORMATICA 2080,25 JURIDICO 2600

NO TA: A ausência da descrição do departamento ou a escolha de outra colunapara a cláusula GROUP BY, fará com que o banco de dados Oracle retorne umamensagem de erro, não executando o comando SELECT.

SELECT D.DESCRICAO,AVG(F.SALARIO) FROM FUNCIONARIO F, DEPTO D WHERE F.DEPTO = D.DEPTO; ausência da cláusula GROUP BY

SELECT D.DESCRICAO,AVG(F.SALARIO) * ORA-00937: não e uma funcão de grupo de grupo simples

SELECT D.DESCRICAO,AVG(F.SALARIO) FROM FUNCIONARIO F, DEPTO D WHERE F.DEPTO = D.DEPTO escolha de outra coluna

GROUP BY D.DEPTO;

SELECT D.DESCRICAO,AVG(F.SALARIO) * ORA-00979: não e uma expressão GROUP BY

Exemplo 2 – Selecionando o nome do funcionário, seus respectivos cargo e depar-tamento, ordenados pelo nome do departamento e cargo.

SELECT F.NOME,D.DESCRICAO, C.DESCRICAO FROM FUNC F, DEPTO D, CARGOS C WHERE F.DEPTO = D.DEPTO and F.CARGO = C.CARGO ORDER BY D.DESCRICAO, C.DESCRICAO;

NOME DESCRICAO DESCRICAO---------------------- ------------------ -------------SERGIO DUSEK INFORMATICA GERENTEARLETTE DUSEK INFORMATICA GERENTE GERALRONALD MUTO INFORMATICA SUPERVISORRAFAEL ZANATTA INFORMATICA SUPERVISOR

Page 49: Delphi 6 com Oracle

50 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

THAIS SABBAG MUTO JURIDICO ADVOGADOPATRICIA DUSEK JURIDICO ADVOGADOANDRE MUTO JURIDICO VETERINARIO

Exemplo 3 – Selecionando o nome do funcionário e departamento, cujo salárioesteja compreendido entre 1500 e 2500, por departamento e nome.

SELECT F.NOME, F.SALARIO, D.DESCRICAO FROM FUNCIONARIO F, DEPTO D WHERE F.DEPTO = D.DEPTO AND F.SALARIO BETWEEN 1000 AND 2500 ORDER BY 3,1;

NOME SALARIO DESCRICAO-------------------------------- ---------- -----------RAFAEL ZANATTA 1930 INFORMATICARONALD MUTO 1500 INFORMATICASERGIO DUSEK 2000 INFORMATICAANDRE MUTO 2350 JURIDICOPATRICIA DUSEK 2450 JURIDICO

Tomemos o exemplo 3, só que sem a cláusula WHERE, e o resultado será o pro-duto cartesiano das duas tabelas.

SELECT F.NOME, F.SALARIO, D.DESCRICAO FROM FUNCIONARIO F, DEPTO D;

NOME SALARIO DESCRICAO-------------------------------- ---------- -----------RONALD MUTO 1500 INFORMATICATHAIS SABBAG MUTO 3000 INFORMATICASERGIO DUSEK 2000 INFORMATICAANDRE MUTO 2350 INFORMATICARAFAEL ZANATTA 1930 INFORMATICAPATRICIA DUSEK 2450 INFORMATICAARLETTE DUSEK 3900 INFORMATICARONALD MUTO 1500 JURIDICOTHAIS SABBAG MUTO 3000 JURIDICOSERGIO DUSEK 2000 JURIDICOANDRE MUTO 2350 JURIDICORAFAEL ZANATTA 1930 JURIDICOPATRICIA DUSEK 2450 JURIDICOARLETTE DUSEK 3900 JURIDICO

Page 50: Delphi 6 com Oracle

51

Parte IV.Integrando Delphi com Oracle

Page 51: Delphi 6 com Oracle

53

8. Transações

Uma transação é uma seqüência de operações que são tratadas como um blocoúnico e indivisível no que se refere à sua recuperabilidade.

Os comandos recebidos para processamento pelo banco de dados Oracle compõemas transações. A transação é a unidade lógica de trabalho, possuindo propriedadesbem definidas, que são garantidas pelos gerenciadores do banco de dados mesmono caso de falhas durante o processamento ou mesmo após o término do processa-mento, como no caso de falha do meio de armazenamento dos dados.

Uma transação é representada por um bloco de comandos DML, onde os dadosdevem ser tornados permanentes (COMMIT) ou desfeitos (ROLLBACK), como noexemplo a seguir:

Início ... UPDATE FUNCIONARIO SET NOME=’PLINIO MUTO’ Comandos DML

WHERE MATRICULA=’001’ ... INSERT INTO FUNCIONARIO VALUES (‘010’,’ARLETTE DUSEK’,1430,’002’); COMMIT; Tornando permanente as alterações

...

TérminoQuando os resultados de uma transação são efetivados, as modificações que even-tualmente tenham sido realizadas no banco de dados Oracle são tornadas visíveispara outras transações. Neste caso, o banco de dados mudou de estado, passou paraum estado diferente do inicial. Caso a transação tenha os seus resultados desfeitos,dizemos que o banco de dados permanece no estado inicial.

Page 52: Delphi 6 com Oracle

54

9. Conexão com o Banco de Dados Oracle viaBDE

B#��8� ��������O BDE administrator funciona com uma interface para o BDE, onde através deleserão configuradas as propriedades para acesso ao banco de dados Oracle.

�������������B#��8� ��������Ao ser carregado no painel de controle do Windows, a seguinte tela deverá serapresentada:

������. �

Page 53: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 55

Na aba Databases estão listados todos os aliases para os banco de dados disponí-veis, que estão exibidos em uma árvore hierárquica ao lado esquerdo da janela. Aoselecionarmos qualquer um, as definições serão exibidas na parte direita da janela.

A aba Configuration exibe e permite que sejam configurados os drivers para acessoaos bancos de dados utilizados pelo Delphi, sendo divididos em Native e ODBC.Ao selecionarmos cada driver, suas configurações serão exibidas na parte direita dajanela.

��������������B#��8� ��������Devemos, agora, criar um novo alias no BDE Administrator para acessarmos obanco de dados Oracle.

As etapas para criação de um novo alias serão demonstradas a seguir:

���!�� �"��������� ����������

Devemos escolher a opção New, no menu Object e, logo após, selecionarmos odriver ORACLE para acesso ao banco. A seguinte tela será exibida:

������. ��

Page 54: Delphi 6 com Oracle

56 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

���!����"�#������������� �����������������!��������������;��#���;����Devemos escolher o nome para o alias criado no BDE, assim como o tipo de servi-ço que será utilizado.

Na janela apresentada a seguir, o nome do alias que utilizaremos para nossosexemplos com o Delphi será ORACLE, e o nome do serviço será o criadoORA_DEL, criado anteriormente.

������. �$

���!��$�"�#�������������!���������������;�������������

Uma vez selecionada a aba Configuration, devemos clicar Configuration->Drivers->Native->ORACLE para em seguida utilizarmos o tipo de serviço cria-do no tópico 2.2 ,ORA_DEL, conforme tela mostrada na figura 9.4:

Page 55: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 57

������. �%

A versão do Oracle que está sendo utilizada é a 8.0.5, logo em DLL32 e VENDORINIT os campos devem ser preenchidos com SQLORA8.DLL e OCI.DLL, respecti-vamente.

Versões anteriores do Oracle utilizam DLLs diferentes, que podem ser consultadasatravés do HELP do próprio Delphi.

���!��%�"����������������������������������B#�8� ��������

Uma vez preenchidas todas as informações descritas antes, um novo alias terá sidocriado, devendo então ser confirmado através da opção Apply, no menu Objects.

Page 56: Delphi 6 com Oracle

58 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

�� !��������6���������������C��A figura 9.5 nos mostra, utilizando os principais componentes, como o Delphitrata o acesso ao banco de dados.

TDatabase TUpDateSql TDataSource

Tquery

������. �(

,#���;���O componente TDatabase nos permite estabelecer uma conexão com o banco dedados Oracle. Se nenhum componente TDatabase for criado explicitamente, o Del-phi irá criá-lo em tempo de execução.

A criação do componente no seu aplicativo irá fornecer um grande poder de con-trole do banco de dados Oracle, permitindo a criação de logins personalizados,controlar transações e criar aliases BDE locais.

A seguir estão listadas as principais propriedades para estabelecermos uma cone-xão com o banco de dados Oracle.

Nome: AliasNameTipo: TSymbolStringDescrição: Nome de um alias BDE existente.

Page 57: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 59

Nome: ConnectedTipo: BooleanDescrição: Indica se foi estabelecida uma conexão com o banco de dados Oracle.

Nome: DataBaseNameTipo: TFileNameDescrição: Define um alias local, específico de um aplicativo.

Nome: LoginPromptTipo: BooleanDescrição: Especifica se a caixa de login será exibida quando o aplicativo tentaruma conexão no banco de dados Oracle.

Nome: ParamsTipo: TStringsDescrição: Especifica os parâmetros necessários para a conexão como o banco dedados Oracle.

,2���O componente TQuery estabelece uma conexão entre um DataSource e um bancode dados ou BDE. Permite que o aplicativo submeta declarações SQL para o bancode dados Oracle. Os dados resultantes são então direcionados para o DataSource afim de fazer a interface com os controles de dados atualizados.

O TQuery pode tanto retornar um conjunto de resultados editáveis como de so-mente para leitura. A execução de uma declaração SQL através de um componenteTQuery é dada através da propriedade SQL. A seguir as principais propriedadesdeste componente.

Nome: DatabaseNameTipo: StringDescrição: Especifica o nome do banco de dados a ser utilizado.

Nome: DataSourceTipo: TDataSourceDescrição: Especifica o componente TDataSource a ser utilizado.

Nome: RequestLiveTipo: BooleanDescrição: Se a propriedade for true e a sintaxe SQL permitir, ele determina queum conjunto de dados editáveis será retornado. Para comandos INSERT,UPDATE, DELETE, COMMIT e ROLLBACK, utilizados na propriedade SQL,

Page 58: Delphi 6 com Oracle

60 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

seu valor deve ser alterado para true. Para o comando SELECT e utilização comcomponente TUpDateSQL, seu valor deve ser alterado para false.

Nome: SQ LTipo: StringDescrição: Armazena uma declaração SQL.

A seguir, os principais métodos deste componente.

Nome: CloseDescrição: Altera o valor da propriedade Active para false.

Nome: ExecSqlDescrição: Executa uma declaração SQL que não retorna um conjunto de resulta-dos.

Nome: O penDescrição: Altera o valor da propriedade Active para true, executando uma decla-ração SQL que não retorne um conjunto de resultados.

,�!�����)�Permite acesso a um componente TQuery associado a uma declaração SQL especí-fica. A seguir as principais propriedades deste componente.

Nome: DeleteSQ LTipo: TStringsDescrição: Codifica um comando DELETE associado a uma string SQL criadanum componente TQuery.

Nome: InsertSQ LTipo: TStringsDescrição: Codifica um comando INSERT associado a uma string SQL criadanum componente TQuery.

Nome: ModifySQ LTipo:TStringsDescrição: Codifica um comando UPDATE associado a uma string SQL criadanum componente TQuery.

Para utilizarmos o TUpDateSQL devemos alterar os valores das seguintes proprie-dades do componente TQuery:

Page 59: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 61

• UpdateObject – deve estar ‘apontando’ para o componente TUpDateSql;• RequestLive – seu valor deve ser false;• SQL – a string contendo o comando SQL deve estar preenchida.

Componentes data controls devem ser criados para referenciar os campos das ins-truções criadas no TUpDateSql.

Mais adiante mostraremos a utilização exata desse componente.

,#��������Permite estabelecer uma conexão entre uma ou mais componentes Data Controls(dbgrids, dbedit, etc.) e em cada componente TTable ou TQuery. A seguir é mos-trada a propriedade mais importante desse componente.

Nome: DataSetTipo: TDataSetDescrição: Especifica o dataset (TTable ou TQuery) do qual o componente obtémseus dados.

,�;����D�2����Como já foi visto, o Delphi possui dois componentes que permitem o acesso e mani-pulação das tabelas, via BDE, contidas no banco de dados Oracle: TTable e TQuery.O primeiro baseia-se no acesso a uma determinada tabela do banco de dados e osegundo é baseado numa seqüência SQL, permitindo dessa forma que trabalhemoscom mais de uma tabela ao mesmo tempo. Ambos utilizam a linguagem SQL paraacessar a base de dados. Quando se trabalha com TTable, o Delphi gera automatica-mente uma sentença SQL de acordo com os parâmetros definidos para o componen-te. Serão analisados no próximo tópico as principais vantagens e desvantagensquanto ao uso desses componentes. Por preferência própria, costumo utilizar o com-ponente Tquery que, alterando suas propriedades de forma correta, funciona commuito mais eficiência na abertura das tabelas, assim como na filtragem das colunas,além de se comportar como um componente TTable em alguns casos.

���������E#����������Ao usar o componente TTable, o BDE solicita ao servidor primeiro a estrutura databela e depois os dados dela. Esses passos são necessários para se configurarem asestruturas internas corretas do BDE e eles não são executados pelo componenteTQuery. Se for ativado o Schema Caching do BDE, a estrutra lógica da tabela émantida localmente, onde esse passo é economizado. Isso pode gerar problemas,caso a estrutura lógica da tabela mude no servidor.

Page 60: Delphi 6 com Oracle

62 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

No componente TTable, o BDE imita um cursor bidirecional colocando os dadoslocalmente em cache. No componente TQuery, o cache pode ser opcional, bastandopara isso alterar a propriedade Unidirectional.

Ao tentar minimizar os dados transferidos entre o cliente e o servidor, o tamanhode cada registro precisa ser considerado, bem como o número total deles. Quandoapenas alguns campos são selecionados para uma consulta, apenas parte dos dadosé considerada. No componente TQuery, quando se envia uma cláusula WHERE nocomando SQL, o próprio servidor se encarrega de selecionar os registros que com-põem a pesquisa realizada, já observando as melhores alternativas de acesso, ten-tando utilizar o máximo de índices estabelecidos no banco de dados Oracle. Ocomponente TTable, a propriedade filter e as funções de seleção SetRange agem deforma diferente, tentando traduzir as especificações feitas através desses dois mé-todos e colocá-las diretamente na cláusula WHERE do SELECT realizado, obtendodessa forma o mesmo desempenho do componente Query. Existe uma certa limita-ção dessas especificações e se não conseguirem ser traduzidas, o filtro será feito naprópria máquina cliente. Dessa forma, no que diz respeito a filtros, o componente émais abrangente, suportando de forma mais complexa a sintaxe fornecida pelobanco de dados Oracle.

O componente TQuery não está limitado somente às instruções select de SQL,podendo ser utilizado para inserir, atualizar ou excluir linhas de uma tabela, onde apropriedade RequestLive deve ser alterada para true. Quando o componenteTQuery é utilizado para realizar comandos que incluem, alteram ou apagam dadosem uma tabela de banco de dados, o método ExecSql deve ser chamado.

�C� !����#��!&�FB#� �D�/����Serão mostrados a seguir exemplos de aplicativos Delphi acessando uma base dedados Oracle, via BDE, utilizando componentes TQuery e componentes TUpda-teSql.

Aplicações que envolvem o uso único e exclusivo de TQuery’s permitem que vári-as transações sejam efetuadas diretamente contra o banco de dados e confirmadasde uma só vez, gerando, dessa forma, um fluxo constante de dados na rede entre ocliente e o servidor.

Em contrapartida, aplicações que utilizam TUpdateSqls não geram fluxo constantede dados na rede, pois as transações são efetuadas na memória da máquina da estaçãocliente, sendo transportadas para o banco de dados somente ao serem confirmadas.

A aplicabilidade de cada um depende diretamente do tipo de sistema que será cria-do e da preferência de cada desenvolvedor/analista.

Page 61: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 63

������������ ��8!���������� �,2���Antes de criarmos nossa aplicação Delphi, devemos primeiro criar as tabelas no bancode dados, utilizando o SQL 8 Plus. Note que em nenhuma das tabelas que serão criadasexiste a constraint FOREIGN KEY com a cláusula DELETE CASCADE, fazendocom que toda a integridade de dados tenha que ser controlada pela nossa aplicação.

� Criando a Tabela de EmpregadosSQL > CREATE TABLE EMPREGADOS 2 (MATRICULA VARCHAR(5) NOT NULL, 3 NOME VARCHAR2(30) NOT NULL, 4 NASCIM DATE NOT NULL, 5 SALARIO NUMBER NULL, 6 ENDERECO VARCHAR2(50) NULL, 7 CONSTRAINT PK_MATRIC PRIMARY KEY (MATRICULA));

� Criando a Tabela de DepartamentosSQL > CREATE TABLE DEPTO 2 (CODDEP VARCHAR2(3) NOT NULL, 3 DESCRICAO VARCHAR2(25) NULL, 4 CONSTRAINT PK_CODDEP PRIMARY KEY (CODDEP));

� Criando a Tabela de Relacionamentos de Empregados com Departamentos:

SQL > CREATE TABLE EMPXDEP (MATRICULA VARCHAR2(5) NOT NULL, CODDEP VARCHAR2(3) NOT NULL);

� Criando a Tabela de Cargos

SQL > CREATE TABLE CARGOS (CODCARGO VARCHAR2(3) NOT NULL, DESCRICAO VARCHAR2(25) NULL, CONSTRAINT PK_CODCARGO PRIMARY KEY (CODCARGO));

� Criando a Tabela de Relacionamentos de Empregados com CargosSQL > CREATE TABLE EMPXCARGO (MATRICULA VARCHAR2(5) NOT NULL, CODCARGO VARCHAR2(3) NOT NULL);

Após criarmos as tabelas no banco de dados, devemos então executar o Delphi paraque possamos construir nossa aplicação. A aplicação será desenvolvida, basica-mente, em duas partes, sendo cada uma composta de várias etapas:

Parte 1 – Criação dos componentes necessários.Parte 2 – Explicação do código gerado para cada componente criado.

Page 62: Delphi 6 com Oracle

64 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

5���� �"�������������� !��������������:���

���!�� �"������������ �����#��� �����

Um novo Datamodule deve ser adicionado ao projeto, vá em File->New->DataModule;

Os seguintes valores deverão ser modificados:

������. �+

O DataModule deverá ser salvo como udmexemplo1.pas

Page 63: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 65

���!����"�8���������(��� !������������;��B#����#��� �����Conforme figura 9.7, 5 componentes deverão ser adicionados:

2 3

1

4 5

������. �-

Os seguintes valores deverão ser modificados:

1 – TDataBase

������. ��

Page 64: Delphi 6 com Oracle

66 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

2 – TQuery 3 – TDataSource

������. �. ������������. � G

4 – TQuery 5 – TDataSource

������. � ����������� ��� �.� �

Page 65: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 67

���!��$�"������������� ��:���!����!�����!������������������� !�������Deveremos criar o pagecontrol que fará parte do projeto, assim como 4 tabsheetsque deverão ter sua propriedade caption setadas para Empregados, Cargos, De-partamentos e Consulta, conforme mostra a figura 9.13:

������. � $

Tabsheet 1

Tabsheet 2 Tabsheet 3

Tabsheet 4

Pagecontrol

Page 66: Delphi 6 com Oracle

68 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

���!��$� �"������������� !�������������;�&���

Tabsheet1

9

������. � %

Não comentarei os labels criados em nenhuma das etapas, pois a única propriedadeque iremos setar de cada um é o caption, que deve ser a mesma das figuras mostra-das.

Os seguintes valores deverão ser modificados:

1

2 34

5

6

7

8

Page 67: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 69

1 – TDBGrid 3 – TEdit

������������� ��� �.� -

4 – TMaskEdit

����������������. � (

������������������������������������������������������������������������������.� �

2 – TEdit 5 – TEdit

������. � + ������. � .

Page 68: Delphi 6 com Oracle

70 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

6 – TEdit 8 – TEdit

������������������.��G ������������������� ���������������������������� ��� �.���

7 – TEdit

������������������.��

9 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton1, Button2,...,Button7, seguindo a ordem da esquerda para a direita. A pro-priedade caption de cada um deve ser alterada conforme a figura 9.14.

Page 69: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 71

���!��$���"������������� !�������������;�&����

Tabsheet2 1

4������. ��$

Os seguintes valores deverão ser modificados:

1 – TDBGrid 2 – TEdit

������. ��(

����������������������.��%

2

3

Page 70: Delphi 6 com Oracle

72 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

3 – TEdit

��������������� ��� �.��+

4 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton8, Button9,...,Button14, seguindo a ordem da esquerda para a direita. A pro-priedade caption de cada um deve ser alterada conforme a figura 9.23.

���!��$�$�"������������� !�������������;�&���$

Tabsheet3 1

4������. ��-

32

Page 71: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 73

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TEdit

������. �$G

����������������� ����. ���

2 – TEdit

��������������� ��� �.��.

Page 72: Delphi 6 com Oracle

74 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

4 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton15, Button16,...,Button21, seguindo a ordem da esquerda para a direita. Apropriedade caption de cada um deve ser alterada conforme a figura 9.27.

���!��$�%�"������������� !�������������;�&���%

Tabsheet4

������. �$

20

1

2

3

45

6

7 8

910 11

12

151413

16 17

18

19

Page 73: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 75

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TRadioButton

��������������������.�$� �������������������������������������������������������������������������.�$%

2 – TRadioButton 4 – TRadioButton

������. �$$ ��������. �$(

Page 74: Delphi 6 com Oracle

76 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

5 – TMaskEdit 7 – TRadioButton

������. �$$ ������. �$(

6 – TEdit 8 – TRadioButton

������. �$- ������. �$.

Page 75: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 77

9 – TRadioButton 11 – TRadioButton

������. �%G ������������� ��� �.�%�

10 – TRadioButton 12 – TEdit

������. �% ������. �%$

Page 76: Delphi 6 com Oracle

78 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

13 – TRadioButton 15 – TEdit

���� ����. �%% ������. �%+

14 – TRadioButton 16 – TGroupBox

������. �%( ������. �%-

Page 77: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 79

17 – TGroupBox 19 – TGroupBox

���� ����. �%� ���������� �.�(G

18 – TGroupBox

�������� �.�%.

Page 78: Delphi 6 com Oracle

80 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

20 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton22, Button23 e Button24, seguindo a ordem da esquerda para a direita. Apropriedade caption de cada um deve ser alterada conforme a figura 9.31.

5������"��C!������������?�����9�����!��������� !������������Antes de iniciarmos a explicação sobre o funcionamento de cada tabsheet, algumasprocedures e funções de uso geral do projeto devem ser criadas.

As quatro procedures a seguir são responsáveis por limpar o conteúdo da proprie-dade text de cada componente contido em sua respectiva tabsheet.

procedure TForm1.limpa_var_deptos;begin edtcoddep.text:= ''; edtdescdep.text:= '';

end;

procedure TForm1.limpa_var_empregados;begin edtmatric.text:= ''; edtnome.text:= ''; mskdata.text:= ' / / '; edtender.text:= ''; edtsalario.text:= ''; edtcargo.text:= ''; edtdepto.text:= '';end;

procedure TForm1.limpa_var_cargos;begin edtcodcargo.text:= ''; edtdesccargo.text:= '';end;

procedure TForm1.limpa_var_consulta;begin mskdata2.text:= ' / / '; mskdata2.enabled:= false; edtcargos2.text:= ''; edtcargos2.enabled:= false; edtdepto2.text:= ''; edtdepto2.enabled:= false; edtmatric2.text:= ''; edtmatric2.enabled:= false;

rbtdfunci.checked:= true; rbslfunci.checked:= false; rbdtcontrat.checked:= false; rbtdcargos.checked:= true;

Page 79: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 81

rbslcargos.checked:= false; rbtddepto.checked:= true; rbsldepto.checked:= false; rbmaisal.checked:= false; rbmensal.checked:= false; rbmedsal.checked:= false;

end;

Para que toda inclusão, alteração e exclusão de registros efetuada no banco de da-dos reflita nos dbgrids do projeto, é necessário fechar e abrir, logo em seguida, aquery associada a ele. A procedure seguinte será a responsável por essa tarefa.

procedure TForm1.executa_refresh;begin datamodule1.query1.close; datamodule1.query1.open;end;

Uma vez que todas as instruções SQL de inclusão, exclusão e alteração serão exe-cutadas na query2, a procedure seguinte evita a replicação de código em nossoprojeto, bastando para isso que passemos como parâmetro a instrução SQL deseja-da.

procedure TForm1.sql_generico(stringsql: string);begin with datamodule1.query2 do begin sql.clear; sql.add(stringsql); execsql; end;

end;

Da mesma forma, as consultas efetuadas em nosso projeto, realizadas através daquery1. Devemos, então, utilizar a procedure a seguir, passando como parâmetro ainstrução SQL e o objeto TQuery desejado.

procedure Tform1.consulta_generica(stringsql: string; pquery: TObject);begin with (pquery as tquery) do begin sql.clear; sql.add(stringsql); open; end;end;

Para evitarmos que códigos de departamentos e cargos não cadastrados sejam in-cluídos em um funcionário, uma vez que o recurso de constraints não foi utilizado,é necessário controlar a integridade dos dados através da função a seguir.

function TForm1.verifica_integridade: boolean;var encontrou: boolean;

Page 80: Delphi 6 com Oracle

82 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

begin encontrou:= false;

consulta_generica('select * from CARGOS where CODCARGO = '+chr(39)+ edtcargo.text+chr(39)+'',datamodule1.query2);

if not ((datamodule1.query2.eof) and (datamodule1.query2.eof)) then begin

consulta_generica('select * from DEPTO where CODDEP = '+chr(39)+ edtdepto.text+chr(39)+'',datamodule1.query2);

if not ((datamodule1.query2.eof) and (datamodule1.query2.eof)) then encontrou:= true else showmessage('Código de departamento não cadastro/encontrado !');

end else showmessage('Código de cargo não cadastro/encontrado !');

if encontrou then result:= true else result:= false;

end;

Todo o controle das transações efetuadas contra o banco de dados são, basicamen-te, realizadas através dos botões contidos em cada tabsheet. A seguir, serão expli-cados, através de etapas, o ‘funcionamento’ de cada tabsheet assim como os even-tos referentes a cada botão.

���!�� �"�,�;�&�����H����������������I

O código de cada evento será comentado após a descrição de cada componente (Anumeração será a mesma utilizada na Parte 1).

TabSheet2

Responsável por incluir, alterar e excluir um cargo.

Evento: OnShow

Código: procedure TForm1.TabSheet2Show(Sender: TObject); begin consulta_generica('select * from CARGOS',datamodule1.query1); limpa_var_cargos; panel2.enabled:= false; end;

Page 81: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 83

Objetivo: Exibir todas as colunas da tabelas CARGOS e seu respectivo conteúdoatravés da query1, limpar a propriedade text dos componentes e alterar o valor dapropriedade enabled para false no panel2, evitando que informações sejam inseri-das sem que antes um dos botões de Incluir ou Alterar seja pressionado.

1 – DbGrid2Exibir informações da tabela CARGOS, através da query1.

Evento: Não existe.

2 – EdtCodCargoArmazenar em memória, até ser transferido para o banco de dados, o código docargo a ser inserido ou alterado.

Evento: Não existe.

3 – EdtDescCargoArmazenar em memória, até ser transferido para o banco de dados, a descrição docargo a ser inserido ou alterado.

Evento: Não existe.

4 – Button8A rotina de inclusão deve ser capaz de colocar a tabsheet2 em condições de inseririnformações nos componentes edtcodcargo e edtdesccargo, onde será transferidoposteriormente para o banco de dados.

Evento: OnClick

Código: procedure TForm1.Button8Click(Sender: TObject); begin pinclui:= true; panel2.enabled:= true; limpa_var_cargos; edtcodcargo.enabled:= true; edtcodcargo.setfocus; end;

Objetivo: Alterar o valor da variável global pinclui, informando ao projeto que umnovo registro será inserido na tabela CARGOS e alterar o valor da propriedadeenabled para true no panel2, permitindo que informações sejam inseridas nos com-ponentes.

4 – Button9A rotina de exclusão deve permitir que um cargo e seu respectivo relacionamentosejam apagados.

Page 82: Delphi 6 com Oracle

84 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Evento: OnClick

Código: procedure TForm1.Button9Click(Sender: TObject); begin sql_generico('delete from cargos where codcargo = '+chr(39)+ datamodu-le1.query1.fieldbyname('codcargo').asstring+chr(39)); sql_generico('delete from empxcargo where codcargo = '+chr(39)+ datamodu-le1.query1.fieldbyname('codcargo').asstring+chr(39)); executa_refresh; end;

Objetivo: Excluir os registros nas tabelas CARGOS e EMPXCARGO, utilizando oregistro corrente da query1, executando logo em seguida um refresh para que aexclusão reflita no dbgrid.

4 – Button10A rotina de alteração deve ser capaz de colocar a tabsheet2 em condições de alteraras informações contidas nos componentes edtcodcargo e edtdesccargo.

Evento: OnClick

Código: procedure TForm1.Button10Click(Sender: TObject); begin with datamodule1.query1 do begin edtcodcargo.text:= fieldbyname('CODCARGO').asstring; edtdesccargo.text:= fieldbyname('DESCRICAO').asstring; end; pinclui:= false; panel2.enabled:= true; edtcodcargo.enabled:= false; edtdesccargo.setfocus; end;

Objetivo: T ransferir os valores dos campos CODCARGO e DESCRICAO, conti-dos no registro corrente da query1, para a propriedade text dos componentes edtco-dcargo e edtdesccargo. Alterar o valor da variável global pinclui, informando aoprojeto que o registro será alterado na tabela CARGOS, alterar o valor da proprie-dade enabled para true no panel2, permitindo que as informações sejam modifica-das nos componentes e, por fim, alterar o valor da propriedade enabled para falseno componente edtcodcargo, pois não devemos alterar o valor da chave primária.

4 – Button11A rotina contida no botão Ok é responsável por transferir as informações contidasnos componentes da tabsheet2 para o banco de dados Oracle, alterando ou inserin-do um registro.

Page 83: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 85

Evento: OnClick

Código: procedure TForm1.Button11Click(Sender: TObject); begin if pinclui then sql_generico('insert into cargos values('+chr(39)+edtcodcargo.text+chr(39)+','+ chr(39)+edtdesccargo.text+chr(39)+')') else sql_generico('update cargos set descricao = ‘+ chr(39)+edtdesccargo.text+chr(39)+ ' where codcargo = ‘+chr(39)+ edtcodcargo.text+chr(39)); limpa_var_cargos; panel2.Enabled:= false; executa_refresh; end;

Objetivo: Verificar através da variável global pinclui se um comando SQL de inclusãoou alteração deve ser executado, transferindo a informação contida na propriedade textde cada componente para a tabela CARGOS1. Alterar o valor da propriedade enabledpara false no panel2 e executar um refresh para que a atualização reflita no dbgrid.

4 – Button12Fica a cargo dessa rotina transformar em permanentes as atualizações pendentesem todas as tabelas do banco de dados.

Evento: OnClick

Código: Deve apontar para o evento Onclick do Button5.

Objetivo: Executar o comando COMMIT no banco de dados e executar um refreshpara que a atualização reflita no dbgrid.

4 – Button13Essa rotina, ao contrário da anterior, cancela as atualizações pendentes em todas astabelas do banco de dados.

Evento: OnClick

Código: Deve apontar para o evento Onclick do Button6.

Objetivo: Executar o comando ROLLBACK no banco de dados e executar um re-fresh para que a atualização reflita no dbgrid.

1 É importante lembrar que as atualizações efetuadas estão pendentes, como já foi explicado.

Page 84: Delphi 6 com Oracle

86 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

���!����"�,�;�&���$�H�����������#�!��� �����ITabSheet3 Responsável por incluir, alterar e excluir um departamento.

Evento: OnShow Código:

procedure TForm1.TabSheet2Show(Sender: TObject); begin consulta_generica('select * from DEPTO',datamodule1.query1); limpa_var_deptos; panel3.enabled:= false; end;

Objetivo: Exibir todas as colunas da tabela DEPTO e seu conteúdo através daquery1, limpar a propriedade text dos componentes e alterar o valor da propriedadeenabled para false no panel3, evitando que, antes de ser pressionado um dos botõesde Incluir ou Alterar, informações sejam inseridas.

1 – DbGrid2Exibir informações da tabela DEPTO, através da query1.

Evento: Não existe.

2 – EdtCodDepArmazenar em memória, o código do cargo a ser inserido ou alterado até que possaser transferido para o banco de dados.

Evento: Não existe.

3 – EdtDescDepArmazenar em memória a descrição do cargo a ser inserido ou alterado até quepossa ser transferido para o banco de dados.

Evento: Não existe.

4 – Button15Esta rotina deve colocar a tabsheet3 em condições de inserir informações nos com-ponentes, para posterior transferência para o banco de dados.

Evento: OnClick

Código: procedure TForm1.Button15Click(Sender: TObject); begin pinclui:= true; panel3.enabled:= true;

Page 85: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 87

limpa_var_deptos; edtcoddep.enabled:= true; edtcoddep.setfocus; end;

Objetivo: Alterar o valor da variável global pinclui, informando que um novo re-gistro será inserido na tabela DEPTO e alterar o valor da propriedade enabled paratrue no panel3.

4 – Button16Esta rotina permite que um departamento e seu respectivo relacionamento sejamapagados.

Evento: OnClick

Código: procedure TForm1.Button16Click(Sender: TObject); begin sql_generico('delete from depto where coddep = '+chr(39)+ datamodule1.query1.fieldbyname('coddep').asstring+chr(39)); sql_generico('delete from empxdep where coddep = '+chr(39)+ datamodule1.query1.fieldbyname('coddep').asstring+chr(39)); executa_refresh; end;

Objetivo: Excluir os registros nas tabelas DEPTO e EMPXDEP, utilizando o re-gistro corrente da query1 e executar em seguida um refresh para que a exclusãoreflita no dbgrid.

4 – Button17A rotina de alteração de um departamento deve ser capaz de colocar a tabsheet3 emcondições de alterar as informações contidas em seus componentes.

Evento: OnClick

Código: procedure TForm1.Button17Click(Sender: TObject); begin with datamodule1.query1 do begin edtcoddep.text:= fieldbyname('CODDEP').asstring; edtdescdep.text:= fieldbyname('DESCRICAO').asstring; end; pinclui:= false; panel3.enabled:= true; edtcoddep.enabled:= false; edtdescdep.setfocus; end;

Objetivo: Os valores dos campos CODDEP e DESCRICAO, contidos no registrocorrente da query1, devem ser transferidos para a propriedade text dos componen-

Page 86: Delphi 6 com Oracle

88 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

tes edtcoddep e edtdescdep. O valor da variável global pinclui será alterado, infor-mando que o registro será alterado na tabela DEPTO. Alterar o valor da proprieda-de enabled para true no panel3, permitindo que as informações sejam modificadasnos componentes e, como não devemos alterar o valor da chave primária, a propri-edade enabled será modificada para false no componente edtcoddep.

4 – Button18A rotina contida no botão Ok é responsável por transferir as informações contidasnos componentes da tabsheet3 para o banco de dados Oracle, alterando ou inserin-do um registro.

Evento: OnClick

Código: procedure TForm1.Button18Click(Sender: TObject); begin if pinclui then sql_generico('insert into depto values('+chr(39)+edtcoddep.text+ chr(39)+','+chr(39)+edtdescdep.text+chr(39)+')') else sql_generico('update depto set descricao = '+chr(39)+edtcoddep.text+ chr(39)+' where coddep = '+chr(39)+edtdescdep.text+chr(39));

limpa_var_deptos; panel3.Enabled:= false; executa_refresh; end;

Objetivo: Em função do valor da variável global pinclui, um comando SQL deinclusão ou alteração deve ser executado, onde a informação contida na proprieda-de text de cada componente será transferida para a tabela DEPTO2. Modificar ovalor da propriedade enabled para false no panel2, executando logo em seguida umrefresh para que a atualização reflita no dbgrid.

4 – Button19Esta rotina transforma em permanente as atualizações pendentes em todas as tabe-las do banco de dados.

Evento: OnClick

Código: Deve apontar para o evento Onclick do Button5.

Objetivo: Executar o comando COMMIT no banco de dados e um refresh para quea atualização reflita no dbgrid.

2 É importante lembrar que as atualizações efetuadas estão pendentes, como já foi explicado.

Page 87: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 89

4 – Button20Ao contrário da anterior, cancela as atualizações pendentes em todas as tabelas dobanco de dados.

Evento: OnClick

Código: Deve apontar para o evento Onclick do Button6.

Objetivo: Executar o comando ROLLBACK no banco de dados e um refresh paraque a atualização reflita no dbgrid.

���!��$�"�,�;�&��� �H������������������:���ITabSheet1Responsável por incluir, alterar e excluir um funcionário.

Evento: OnShow

Código:

procedure TForm1.tabsheet1Show(Sender: TObject); begin consulta_generica('select * from EMPREGADOS',datamodule1.query1); limpa_var_empregados; panel1.enabled:= false; end;

Objetivo: Exibir da tabela EMPREGADOS, as colunas e seu conteúdo através daquery1, limpar a propriedade text dos componentes e alterar o valor da propriedadeenabled para false no panel1, evitando que, antes de ser pressionado um dos botõesde Incluir ou Alterar, informações sejam inseridas.

1 – DbGrid1Exibir informações da tabela EMPREGADOS, através da query1.

Evento: Não existe.

2 – EdtMatricArmazenar em memória o número da matrícula do funcionário a ser inserida oualterada até que possa ser transferido para o banco de dados.

Evento: Não existe.

3 – EdtNomeArmazenar em memória o nome do funcionário a ser inserido ou alterado.

Evento: Não existe.

Page 88: Delphi 6 com Oracle

90 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

4 – MskDataArmazenar em memória a data de contratação do funcionário a ser inserido ou alte-rado.

Evento: Não existe.

5 – EdtEnderArmazenar em memória o endereço do funcionário a ser inserido ou alterado.

Evento: Não existe.

6 – EdtSalarioArmazenar em memória o salário do funcionário a ser inserido ou alterado.

Evento: Não existe.

7 –EdtCargosArmazenar em memória o cargo do funcionário a ser inserido ou alterado.

Evento: Não existe.

8 – EdtDeptoArmazenar em memória o departamento do funcionário a ser inserido ou alterado.

Evento: Não existe.

9 – Button1A rotina de inclusão deve colocar a tabsheet1 em condições de inserir informaçõesem seus componentes, para transferi-las posteriormente para o banco de dados.Evento: OnClick

Código:

procedure TForm1.Button1Click(Sender: TObject); begin pinclui:= true; panel1.enabled:= true; limpa_var_empregados; edtmatric.enabled:= true; edtmatric.setfocus; end;

Objetivo: Alterar o valor da variável global pinclui, informando que na tabela EM-PREGADOS um novo registro será inserido e alterar o valor da propriedade ena-bled para true no panel1.

Page 89: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 91

9 – Button2Permite que um funcionário seja apagado, assim como seus relacionamentos entredepartamento e cargo.

Evento: OnClick

Código:

procedure TForm1.Button2Click(Sender: TObject); begin sql_generico('delete from empregados where matricula = '+chr(39)+ datamodule1.query1.fieldbyname('MATRICULA').asstring+chr(39)); sql_generico('delete from empxdep where matricula = '+chr(39)+ datamodule1.query1.fieldbyname('MATRICULA').asstring+chr(39)); sql_generico('delete from empxcargo where matricula = '+chr(39)+ datamodule1.query1.fieldbyname('MATRICULA').asstring+chr(39)); executa_refresh; end;

Objetivo: Excluir o registro nas tabelas EMPREGADOS, EMPXCARGO, EM-PXDEP utilizando o registro corrente da query1, onde logo em seguida um refreshé executado para que a exclusão reflita no dbgrid.

9 – Button3A alteração deve ser capaz de modificar as informações contidas nos componentespertencentes a tabsheet1.

Evento: OnClick

Código:

procedure TForm1.Button3Click(Sender: TObject); var pmatric, stringsql: string;

begin pinclui:= false; panel1.enabled:= true; limpa_var_empregados; edtmatric.enabled:= false; edtnome.setfocus; datamodule1.query2.requestlive:= false; pmatric:= datamodule1.query1.fieldbyname('matricula').asstring; stringsql:= 'select emp.matricula, emp.nome, emp.nascim,'+ 'emp.salario, emp.endereco, emxde.coddep, '+ 'emxca.codcargo '+ 'from empregados emp, empxdep emxde, '+ ' empxcargo emxca '+ 'where emp.matricula = '+chr(39)+pmatric+chr(39)+' and '+ ' emxde.matricula = '+chr(39)+pmatric+chr(39)+' and '+ ' emxca.matricula = '+chr(39)+pmatric+chr(39); with datamodule1.query2 do begin

Page 90: Delphi 6 com Oracle

92 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

sql.clear; sql.add(stringsql); open; edtmatric.text:= fieldbyname('matricula').asstring; edtnome.text:= fieldbyname('nome').asstring; mskdata.text:= fieldbyname('nascim').asstring; edtsalario.text:= fieldbyname('salario').asstring; edtender.text:= fieldbyname('endereco').asstring; edtcargo.text:= fieldbyname('codcargo').asstring; edtdepto.text:= fieldbyname('coddep').asstring; end; datamodule1.query2.requestlive:= true; end;

Objetivo: Transferir os valores dos campos da tabela EMPREGADOS, contidos noregistro corrente da query1, para a propriedade text dos componentes da tabsheet1.Alterar o valor da variável global pinclui, informando que o registro será alterado,modificar o valor da propriedade enabled para true no panel2, permitindo que asinformações sejam modificadas e mudar o valor da propriedade enabled para falseno componente edtcodcargo, pois o valor da chave primária não pode ser alterado.

9 – Button4O botão Ok é responsável por transferir as informações contidas nos componentesda tabsheet1 para o banco de dados Oracle, alterando ou inserindo um registro.

Evento: OnClick

Código:

procedure TForm1.Button4Click(Sender: TObject); begin if verifica_integridade then begin if pinclui then begin sql_generico('insert into empregados values('+ chr(39)+edtmatric.text+chr(39)+','+ chr(39)+edtnome.text+chr(39)+','+ chr(39)+mskdata.text+chr(39)+','+ floattostr(strtofloat(edtsalario.text))+','+ chr(39)+edtender.text+chr(39)+')'); sql_generico('insert into empxdep values('+ chr(39)+edtmatric.text+chr(39)+','+ chr(39)+edtdepto.text+chr(39)+')'); sql_generico('insert into empxcargo values('+ chr(39)+edtmatric.text+chr(39)+','+ chr(39)+edtcargo.text+chr(39)+')'); end else begin sql_generico('update empregados '+ 'set nome = '+chr(39)+edtnome.text+chr(39)+ ' ,nascim = '+chr(39)+mskdata.text+chr(39)+ ' ,salario = '+chr(39)+ floattostr(strtofloat(edtsalario.text))+chr(39)+ ' ,endereco = '+chr(39)+edtender.text+chr(39)+

Page 91: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 93

' where matricula = '+chr(39)+edtmatric.text+chr(39)); sql_generico('update empxdep '+ 'set coddep = '+chr(39)+edtdepto.text+chr(39)+ 'where matricula = '+chr(39)+edtmatric.text+chr(39)); sql_generico('update empxcargo '+ 'set codcargo = '+chr(39)+edtcargo.text+chr(39)+ 'where matricula = '+chr(39)+edtmatric.text+chr(39)); end; end; limpa_var_empregados; panel1.enabled:= false; executa_refresh; end;

Objetivo: Em função do valor da variável global pinclui, um comando SQL deinclusão ou alteração deve ser executado, transferindo o conteúdo da propriedadetext de cada componente para a tabela EMPREGADOS3. É importante observarque não foram criadas constraints para nossas tabelas; dessa forma, antes de inclu-irmos um funcionário, é necessário chamar a função verifica_integridade que che-ca se os valores contidos nas propriedades text dos componentes edtcargo eedtdepto existem, respectivamente, nas tabelas CARGOS e DEPTO, evitando dessaforma que se cadastre para um funcionário um cargo ou departamento inexistente.É preciso modificar o valor da propriedade enabled para false no panel1, executan-do logo em seguida um refresh para que a atualização reflita no dbgrid.

9 – Button5Esta rotina altera para permanente as atualizações pendentes em todas as tabelas dobanco de dados.

Evento: OnClick

Código:

procedure TForm1.Button5Click(Sender: TObject); begin sql_generico('commit'); executa_refresh; end;

Objetivo: Executar o comando COMMIT no banco de dados e um refresh para quea atualização reflita no dbgrid.

9 – Button6Cancelar as atualizações pendentes em todas as tabelas do banco de dados.

3 É importante lembrar que as atualizações efetuadas estão pendentes, como já foi explicado.

Page 92: Delphi 6 com Oracle

94 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Evento: OnClick

Código:

procedure TForm1.Button6Click(Sender: TObject); begin sql_generico('rollback'); executa_refresh; end;

Objetivo: Executar o comando ROLLBACK no banco de dados e um refresh paraque a atualização reflita no dbgrid.

���!��%�"�,�;�&���%�H��������������������:�������������I

Antes de iniciar a explicação do código gerado para esse formulário de consulta,quero deixar claro que, por fugir ao escopo do que será exposto, não irei comentaro código criado em componente TRadioButton, pois sua finalidade é, única e ex-clusivamente, a de controlar a entrada em cada um deles.

TabSheet4Responsável por consultar um funcionário, seu respectivos cargo e departa-mento.

Evento: OnShow

Código: procedure TForm1.tabsheet4Show(Sender: TObject); begin limpa_var_consulta; end;

Objetivo: Limpar a propriedade text de todos os componentes da tabsheet4.

20 – Button22Gerar a consulta para um funcionário, em função dos valores informados nos com-ponentes contidos na tabsheet4.Evento: OnClick

Código:

procedure TForm1.Button19Click(Sender: TObject); var stringsql: string; lescolheu_sal: boolean; ind: integer;

Page 93: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 95

begin ind:= 0; lescolheu_sal:= false;

pselect:= 'SELECT Empregados.MATRICULA, Empregados.Nome, '+ ' Empregados.SALARIO,'+ ' Empregados.NASCIM, Cargos.DESCRICAO, '+ ' Depto.DESCRICAO ';

pfrom:= ' FROM EMPREGADOS Empregados, EMPXCARGO Empxcargo,'+ ' EMPXDEP Empxdep,'+ ' CARGOS Cargos, DEPTO2 Depto '; pwhere:= ' WHERE (Empregados.MATRICULA = Empxcargo.MATRICULA) '+ ' AND (Cargos.CODCARGO = Empxcargo.CODCARGO) '+ ' AND (Empregados.MATRICULA = Empxdep.MATRICULA) '+ ' AND (Depto.CODDEP = Empxdep.CODDEP) '; pgroup:= '';

if rbmaisal.checked then begin pselect:= 'SELECT MAX(Empregados.SALARIO)'; lescolheu_sal:= true; end;

if rbmensal.checked then begin pselect:= 'SELECT MIN(Empregados.SALARIO)'; lescolheu_sal:= true; end;

if rbmedsal.checked then begin pselect:= 'SELECT AVG(Empregados.SALARIO)'; lescolheu_sal:= true; end;

if lescolheu_sal then begin pselect:= pselect + ',Depto.DESCRICAO '; pgroup:= 'GROUP BY Depto.DESCRICAO'; end;

with datamodule1.query1 do begin sql.clear;

if rbsldepto.checked then begin pwhere:= pwhere+' AND (Depto.CODDEP = '+#39+ edtdepto.text+#39+')'; end;

if rbslcargos.checked then begin pwhere:= pwhere+' AND (Cargos.CODCARGO ='+#39+ edtcargos.text+#39+')'; end;

if not lescolheu_sal then begin if rbslfunci.checked then begin pwhere:= pwhere+' AND (Empregados.MATRICULA = '+#39+; edtdmatric.text+#39+')'; end;

Page 94: Delphi 6 com Oracle

96 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

if rbdtcontrat.checked then begin pwhere:= pwhere+' AND (Empregados.NASCIM = '+#39+; mskdata.text+#39+')'; end; end;

stringsql:= pselect+pfrom+pwhere+pgroup; sql.add(stringsql); open; end; end;

Objetivo: Criar uma consulta, utilizando as tabelas FUNCIONARIOS, DEPTO,CARGOS, EMPXDEP, EMPXCARGO, através de 4 variáveis, que irão compor ocomando SELECT. Sendo elas:

• pselect – Escolhe os campos que serão exibidos pela consulta;• pfrom – Seleciona as tabelas da consulta;• pwhere – Seleciona a condição da consulta;• pgroup – Agrupa os dados, se necessário, da consulta.

Cada variável recebe um valor inicial, podendo ser inteiramente modificado ouconcatenado com outro, variando conforme a escolha de alguma opção da telade consulta. Ao final, seus valores serão somado s em uma única variável:stringsql.

Exemplo 1:

Selecionar todos os funcionários que trabalham no departamento cujo código éidentificado pelo valor ‘01’.

Nesse tipo de escolha não será alterado o valor das variáveis pselect, pfrom epgroup. O único valor alterado será o de pwhere, sendo adicionado ao final davariável o código que irá incluir a condição para que só os funcionários dodepartamento ‘01’ sejam exibidos.

Exemplo 2:

Selecionar a média salarial de todos os funcionários que trabalham em cada depar-tamento da empresa.

A consulta a ser gerada modificará o valor das variáveis pselect, que exibirá so-mente a coluna que conterá a média salarial, através de uma função de grupo(AVG), e pgroup, necessária para agruparmos a média por departamento. As de-mais variáveis permanecem com seus valores iniciais.

Page 95: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 97

O bservação: A consulta é gerada através de um join realizado nas cinco tabelascriadas, onde obteremos de cada uma a informação necessária. A figura 9.51 nosmostra o relacionamento de cada tabela:

Obtém o nome do departamento em Obtém o nome do cargo de que cada funcionário trabalha. cada funcionário da empresa.

������. �(

������������ ���!���������� �,�!�����)�Ao criarmos nossas tabelas no banco de dados para o próximo exemplo, utilizare-mos a constraint FOREIGN KEY com a cláusula DELETE CASCADE, o que fazcom que toda a integridade de dados passe a ser controlada pelo banco de dadosOracle.

� Criando a tabela de empregados:

SQL > CREATE TABLE EMPREGADOS2 2 (MATRICULA VARCHAR2(5) NOT NULL, 3 NOME VARCHAR2(30) NOT NULL, 4 NASCIM DATE NULL, 5 SALARIO NUMBER NULL, 6 ENDERECO VARCHAR2(50) NULL, 7 CONSTRAINT PK_MATRIC PRIMARY KEY (MATRICULA));

� Criando a tabela de cargos:SQL > CREATE TABLE CARGOS2 2 (CODCARGO VARCHAR2(3) NOT NULL, 3 DESCRICAO VARCHAR2(25) NULL, 4 CONSTRAINT PK_CODCARGO2 PRIMARY KEY (CODCARGO));

Page 96: Delphi 6 com Oracle

98 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

� Criando a tabela de relacionamentos de empregados com cargos:

SQL > CREATE TABLE EMPXCARGO2 2 (MATRICULA VARCHAR2(5) NOT NULL, 3 CODCARGO VARCHAR2(3) NOT NULL, 4 CONSTRAINT FK_CODCARGO FOREIGN KEY (CODCARGO) 5 REFERENCES CARGOS2(CODCARGO) ON DELETE CASCADE, 6 CONSTRAINT FK_MATRIC FOREIGN KEY (MATRICULA) 7 REFERENCES EMPREGADOS2(MATRICULA) ON DELETE CASCADE);

� Criando a tabela de departamentos:

SQL > CREATE TABLE DEPTO2 2 (CODDEP VARCHAR2(3) NOT NULL, 3 DESCRICAO VARCHAR2(30) NULL, 4 CONSTRAINT PK_CODDEP2 PRIMARY KEY (CODDEP));

� Criando a tabela de relacionamentos de empregados com departamentos:

SQL > CREATE TABLE EMPXDEP2 2 (MATRICULA CHAR(5) NOT NULL, 3 CODDEP CHAR(3) NOT NULL, 4 CONSTRAINT FK_MATRI FOREIGN KEY (MATRICULA) 5 REFERENCES EMPREGADOS2(MATRICULA) ON DELETE CASCADE, 6 CONSTRAINT FK_CODDEP FOREIGN KEY (CODDEP) 7 REFERENCES DEPTO2(CODDEP) ON DELETE CASCADE);

Após criarmos as tabelas da nossa aplicação, devemos então executar o Delphi.

A aplicação será desenvolvida, conforme o exemplo 1, em duas partes:

Parte 1 – Criação dos componentes necessários;Parte 2 – Explicação do código gerado para cada componente criado.

5���� �"�������������� !��������������:���

���!�� �"������������ �����#��� �����

Um novo Datamodule deve ser adicionado ao projeto.

Vá em File->New->DataModule;

Page 97: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 99

Os seguintes valores deverão ser modificados:

������. �(�

O DataModule deverá ser salvo como udmexemplo1.pas

���!����"�8��������� ���� !������������;��B#����#��� �����Conforme figura 9.53, 18 componentes deverão ser adicionados:

������. �($

1

3 2 4

6 5 7

8

11

14

9

12

15

10

13

16

18

17

Page 98: Delphi 6 com Oracle

100 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

O número bem superior de componentes criados para essa aplicação se deve aofato de termos uma transação em separado para cada tabsheet, o que nos leva acriar um componente TUpdateSql para cada uma.

Os seguintes valores deverão ser modificados:

1 – TDataBase

������. �(%

Será explicada a seguir a utilização detalhada do componente TUpdateSql emconjunto com o TQuery.

• Criar um comando SELECT, utilizando a propriedade SQL do query1, seleci-onando os campos da tabela EMPREGADOS2;

Page 99: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 101

2 – TQuery

������. �((

• Criar os comandos SQL, utilizando o UpdateSql Editor, para inserir, alterar eapagar dados na tabela EMPREGADOS2, utilizando o componenteTUpdateSql;

3 – TUpdateSql

��������������������.�(+

Page 100: Delphi 6 com Oracle

102 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

• Executar o UpdateSql Editor através do botão direito do mouse;

������. �(-

• Selecionar, através da aba Options, os campos que serão atualizados, os cam-pos-chave, gerar e, logo após, verificar o comando SQL criado;

Campos-chave

Tabela

selecionada

através do Campos a

componente serem atualizados

Query1

Botão que cria o comando SQL para

incluir, alterar e apagar linhas na tabela EMPREGADOS2

������. �(�

Page 101: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 103

• Verificando o comando SQL criado para alterar, inserir e apagar linhas na ta-bela EMPREGADOS2;

������. �(.

4 – TDataSource

������. �+G

Page 102: Delphi 6 com Oracle

104 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

• Criar um comando SELECT, utilizando a propriedade SQL do query2, seleci-onando os campos da tabela CARGOS2:

5 – TQuery

������. �+

• Criar os comandos SQL, utilizando o UpdateSql Editor, para inserir, alterar eapagar dados na tabela CARGOS2, utilizando o componente TUpdateSql.

NO TA: Como a criação desses comandos é idêntica a todos os componentes TU-pdateSql, não irei explicar as etapas novamente, onde somente as figuras serãomostradas.

Page 103: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 105

6 – TUpdateSql

UpdateSql Editor

������. �+�

Page 104: Delphi 6 com Oracle

106 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

7 – TDataSource

��������������� ��� �.�+$

• Criar um comando SELECT, utilizando a propriedade SQL do query3, seleci-onando os campos da tabela DEPTO2;

8 – TQuery

������. �+%

Page 105: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 107

• Criar os comandos SQL, utilizando o UpdateSql Editor, para inserir, alterar eapagar dados na tabela DEPTO2, utilizando o componente TUpdateSql.

9 – TUpdateSql

UpdateSql Editor

������. �+(

Page 106: Delphi 6 com Oracle

108 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

10 – TDataSource

����������������� ����. �++

• Criar um comando SELECT, utilizando a propriedade SQL do query4, seleci-onando os campos da tabela EMPXDEP2;

11 – TQuery

������. �+-

Page 107: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 109

• Criar os comandos SQL, utilizando o UpdateSql Editor, para inserir, alterar eapagar dados na tabela EMPXDEP2, utilizando o componente TUpdateSql.

12 – TUpdateSql

UpdateSql Editor

������. �+�

Page 108: Delphi 6 com Oracle

110 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

13 – TDataSource

������ ����. �+.

• Criar um comando SELECT, utilizando a propriedade SQL do query5, seleci-onando os campos da tabela EMPXCARGO2;

14 – TQuery

������. �-G

Page 109: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 111

• Criar os comandos SQL, utilizando o UpdateSql Editor, para inserir, alterar eapagar dados na tabela EMPXCARGO2, utilizando o componente TUpdateSql.

15 – TUpdateSql

������. �-

Page 110: Delphi 6 com Oracle

112 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

16 – TDataSource 18 – TDataSource

������. �-� ������������. �-%

17 – TQuery

������. �-$

Page 111: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 113

���!��$�"������������� ��:���!����!�����!������������������� !�������Uma vez criados os componentes no TdataModule, deveremos, então, criar o page-control, assim como 6 tabsheets que deverão ter sua propriedade Caption setadaspara Empregados, Cargos, Departamentos e Consulta, Empregados X Cargos, Em-pregados X Departamentos conforme mostra a figura 9.75:

������. �-(

���!��$� �"������������� !�������������;�&���

Tabsheet1

������. �-+

Tabsheet 1 Tabsheet 2

Tabsheet 3

Tabsheet 4

Pagecontrol

Tabsheet 5

Tabsheet 6

1

23

45

6

7

Page 112: Delphi 6 com Oracle

114 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Os seguintes valores deverão ser modificados:

1 – TDBGrid 2 – TDBEdit

������. �-- ������������� ��� ��.�-�

3 – TDBEdit 4 – TDBEdit

�������� �.�-. ������������ �.��G

Page 113: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 115

5 – TDBEdit 6 – TDBEdit

������. �� ����������� ��� �.���

7 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton1, Button2,...,Button6, seguindo a ordem da esquerda para a direita. A pro-priedade caption de cada um deve ser alterada conforme a figura 9.76.

���!��$���"������������� !�������������;�&����

Tabsheet2

4������ ����. ��$

1

23

Page 114: Delphi 6 com Oracle

116 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TDBEdit

�������.��% ������������. ��+

2 – TDBEdit

������. ��(

Page 115: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 117

4 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton7, Button8,...,Button12, seguindo a ordem da esquerda para a direita. A pro-priedade caption de cada um deve ser alterada conforme a figura 9.83.

���!��$�$�"������������� !�������������;�&���$

Tabsheet3

������. ��-

1

23

4

Page 116: Delphi 6 com Oracle

118 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TDBEdit

������. ��� �� �����������������������������. �.G

2 – TDBEdit

������������������.��.

Page 117: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 119

4 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton13, Button14,...,Button18, seguindo a ordem da esquerda para a direita. Apropriedade caption de cada um deve ser alterada conforme a figura 9.87.

���!��$�%�"������������� !�������������;�&���%

Tabsheet4

������. �.

20

1

2

3

45

6

78

9

10 1112

151413

16 17

18

19

Page 118: Delphi 6 com Oracle

120 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TRadioButton

������. �.� ������. �.%

2 – TRadioButton 4 – TRadioButton

������. �.$ ��������������. �.(

Page 119: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 121

5 – TMaskEdit 7 – TRadioButton

������. �.+ ������� ��� ������������������.�.�

6 – TEdit 8 – TRadioButton

������. �.- ������������. �..

Page 120: Delphi 6 com Oracle

122 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

9 – TRadioButton 11 – TRadioButton

������. � GG ������������. � G�

10 – TRadioButton 12 – TEdit

�������.� G ������. � G$

Page 121: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 123

13 – TRadioButton 15 – TEdit

���� ������. � G% �������.� G+

14 – TRadioButton 16 – TGroupBox

�������� �.� G( ������. � G-

Page 122: Delphi 6 com Oracle

124 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

17 – TGroupBox 19 – TGroupBox

������. � G� ��������������. � G

18 – TGroupBox

��������������������.� G.

Page 123: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 125

20 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton19, Button20 e Button33, seguindo a ordem da esquerda para a direita. Apropriedade caption de cada um deve ser alterada conforme a figura 9.91.

���!��$�(�"������������� !�������������;�&���(

Tabsheet5

������. �

1

2

3

4

Page 124: Delphi 6 com Oracle

126 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TDBEdit

��������������������.� � �� ���������������������������. � %

2 – TDBEdit

������. � $

Page 125: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 127

4 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton21, Button22,...,Button26, seguindo a ordem da esquerda para a direita. Apropriedade caption de cada um deve ser alterada conforme a figura 9.111.

���!��$�+�"������������� !�������������;�&���+

Tabsheet6

������. � (

1

2

3

4

Page 126: Delphi 6 com Oracle

128 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TDBEdit

������. � + ����������� ��� �.� �

2 – TDBEdit

������. � -

Page 127: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 129

4 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton27, Button28,...,Button31, seguindo a ordem da esquerda para a direita. Apropriedade caption de cada um deve ser alterada conforme a figura 9.115.

5������"��C!������������?�����������!��������� !������������Antes de iniciarmos a explicação do código gerado, convém lembrar que, ao con-trário do exemplo1, onde as operações de inserção, deleção, alteração e mudançade estado dos dados se processavam diretamente no banco de dados Oracle, ondeera necessário gerar uma string para cada uma dessas operações em nosso projeto,isso não ocorrerá nesse exemplo.

As operações se processam na memória da máquina da estação, onde fica todo ocontrole das transações. Somente após a confirmação, via evento applyupdates noscomponentes TQuery criados, é que os dados são transportados para o banco dedados Oracle. Perceba que componentes TDBEdit foram criados, ou seja, não es-tamos mais trabalhando com variáveis de memória (TEdit) e sim, acessando osdados direto do banco, via TQuery. Dessa forma, nossos comandos para inserir,alterar, deletar, confirmar ou cancelar dados serão executados diretamente sobre oscomponentes TQuery a que os componentes TDBEdit estiverem apontando.

Não será necessário, como no exemplo1, criar procedures para verificar a integri-dade dos dados, pois as constraints foram definidas na criação das tabelas do pro-jeto, efetuando assim, essas operações automaticamente.

Então, iniciaremos a explicação sobre o funcionamento de cada tabsheet, ondealgumas procedures e funções de uso geral do projeto devem ser criadas.

As três procedures a seguir são responsáveis por limpar o conteúdo da propriedadetext de cada componente contido em sua respectiva tabsheet.

procedure TForm1.limpa_var_generico(pdbedit1, pdbedit2: tobject);begin (pdbedit1 as tdbedit).text:= ''; (pdbedit2 as tdbedit).text:= '';end;

procedure TForm1.limpa_var_empregados;begin dbmatric.text:= ''; dbnome.text:= ''; dbdata.text:= ' / / '; dbender.text:= ''; dbsalario.text:= '';end;

Page 128: Delphi 6 com Oracle

130 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

procedure TForm1.limpa_var_consulta;begin mskdata2.text:= ' / / '; mskdata2.enabled:= false; edtcargos2.text:= ''; edtcargos2.enabled:= false; edtdepto2.text:= ''; edtdepto2.enabled:= false; edtmatric2.text:= ''; edtmatric2.enabled:= false;

rbtdfunci.checked:= true; rbslfunci.checked:= false; rbdtcontrat.checked:= false; rbtdcargos.checked:= true; rbslcargos.checked:= false; rbtddepto.checked:= true; rbsldepto.checked:= false; rbmaisal.checked:= false; rbmensal.checked:= false; rbmedsal.checked:= false;end;

Conforme o exemplo1, antes de iniciarmos a explicação sobre o funcionamento decada tabsheet, algumas procedures e funções de uso geral do projeto devem sercriadas.

procedure Tform1.consulta_generica(stringsql: string; pquery: TObject);begin with (pquery as tquery) do begin sql.clear; sql.add(stringsql); prepare; open; end;end;

Para que toda inclusão, alteração e exclusão de registros efetuada no banco dedado s reflita nos dbgrids do projeto, é necessário fechar e abrir, logo em segui-da, a query associada a ele. A procedure seguinte será a responsável por essatarefa.:procedure Tform1.executa_refresh(pquery: TObject);begin (pquery as tquery).active:= false; (pquery as tquery).active:= true;end;

Note que, por uma economia de código em nosso projeto, é passado como pa-râmetro o componente TQuery em que efetuaremos o refresh, pois, ao contrá-rio, seríamos obrigado s a utilizar essa procedure em todos os TQuery de nossaaplicação.

Page 129: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 131

As procedures a seguir são responsáveis por colocar o componente TQuery, a que ocomponente TBDEdit se refere, em modo de inserir ou alterar dados, efetuandotambém o controle em alguns componentes da tabsheet correspondente:

procedure TForm1.insert_generico(ppanel, pquery, pdbedit: TObject);begin (Ppanel as Tpanel).enabled:= true; (Pquery as Tquery).insert; (Pdbedit as tdbedit).enabled:= true;end;

procedure TForm1.edit_generico(ppanel, pquery, pdbedit1, pdbedit2: TObject);begin (ppanel as tpanel).enabled:= true; (pdbedit1 as tdbedit).enabled:= false; (pdbedit2 as tdbedit).setfocus; (pquery as tquery).edit;end;

A necessidade de parâmetros nessas procedures segue a mesma linha de raciocíniodas procedures criadas anteriormente.

Conforme explicado no início da Parte 2 desse exemplo, a confirmação para trans-ferência dos dados para o banco de dados Oracle, assim como o cancelamento,deve se processar no componente TQuery. Sendo assim, a procedure seguinte éresponsável por realizar essa operação:

procedure tform1.conf_canc_generico(pquery: tobject; confirma: boolean);begin if confirma then (pquery as tquery).applyupdates else (pquery as tquery).cancelupdates;

executa_refresh(pquery);end;

���!�� �"�,�;�&�����H����������������IO código de cada evento será comentado após a descrição de cada componente (Anumeração será a mesma utilizada na Parte 1).

TabSheet2 Responsável por incluir, alterar e excluir um cargo.

Evento: OnShow Código: procedure TForm1.TabSheet2Show(Sender: TObject); begin panel2.enabled:= false; limpa_var_generico(dbcodcargo,dbdesccargo); end;

Page 130: Delphi 6 com Oracle

132 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Objetivo: Exibir todas as colunas da tabelas CARGOS2 e seu respectivo conteúdo,limpar a propriedade text dos componentes e alterar o valor da propriedade enabledpara false no panel2, evitando que informações sejam inseridas sem que antes umdos botões de Incluir ou Alterar seja pressionado.

Como o DBGrid2 está ligado diretamente ao componente DataSource2, não preci-saremos criar uma string SQL com o comando ‘SELECT ...’, conforme o exem-plo1, pois meu comando SQL já foi criado no componente TQuery2.

1 – DbGrid2Exibir informações da tabela CARGOS2, através da query2.Evento: Não existe.

2 – DbCodCargoArmazenar em memória, até ser transferido para o banco de dados, a coluna docódigo do cargo a ser inserido ou alterado.Evento: Não existe.

3 – EdtDescCargoArmazenar em memória, até ser transferida para o banco de dados, a coluna dadescrição do cargo a ser inserido ou alterado.Evento: Não existe.

4 – Button7A rotina de inclusão deve ser capaz de colocar a tabsheet2 em condições de inseririnformações nos componentes dbcodcargo e dbdesccargo objetivando a posteriortransferência para o banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button7Click(Sender: TObject); begin insert_generico(panel2,datamodule1.query2,dbcodcargo); limpa_var_generico(dbcodcargo,dbdesccargo); dbcodcargo.setFocus; end;

Objetivo: Alterar o valor da propriedade enabled para true no panel2, permitindoque informações sejam inseridas nos componentes, colocar a query2 no modo deinserção, através da função insert_generico.

4 – Button8A rotina de exclusão deve permitir que um cargo e seu respectivo relacionamento,através da constraint criada, sejam apagados.

Page 131: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 133

Evento: OnClickCódigo: procedure TForm1.Button8Click(Sender: TObject); begin datamodule1.query2.delete; end;

Objetivo: Excluir os registros nas tabelas CARGOS2 e EMPXCARGO2, utilizandodiretamente o evento delete da query2.

Diferente do exemplo1, onde era necessário apagar todos os relacionamentos en-volvendo a tabela CARGOS2 (EMPXCARGO2), a constraint criada no banco dedados Oracle realiza essa tarefa.

4 – Button9A rotina de alteração deve ser capaz de colocar a tabsheet2 em condições de alteraras informações contidas nos componentes dbcodcargo e dbdesccargo.

Evento: OnClickCódigo: procedure TForm1.Button9Click(Sender: TObject); begin limpa_var_generico(dbcodcargo,dbdesccargo); edit_generico(panel2,datamodule1.query2,dbcodcargo,dbdesccargo); end;

Objetivo: Colocar a query2 em modo de alteração, através da função edit_generico,para que o conteúdo do registro corrente possa ser modificado, uma vez que, coma utilização de componentes DBEdit, estamos trabalhando diretamente com o re-gistro da tabela.

4 – Button10Esta rotina deve tornar permanente a atualização pendente na query2, transferindoentão o registro para a tabela CARGOS2.

Evento: OnClickCódigo: procedure TForm1.Button10Click(Sender: TObject); begin conf_canc_generico(datamodule1.query2,true); end;

Objetivo: Executar o comando applyupdates na query2, através da funçãoconf_canc_generico, onde a transação pendente será transportada para o banco de da-dos, sendo o registro, então, inserido ou alterado efetivamente na tabela CARGOS2.

Page 132: Delphi 6 com Oracle

134 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

No exemplo1, o COMMIT gerado no botão Confirma transformava em permanenteTODAS as transações pendentes no banco de dados Oracle, pois o comando eradisparado diretamente contra ele. Nesse exemplo apenas a transação realizada natabela CARGOS2, através da query2, é transformada em permanente, ficando asdemais, realizadas através de outras querys, pendentes.

4 – Button11Esta rotina, ao contrário da anterior, deve cancelar a atualização pendente naquery2, retornando ao estado inicial.

Evento: OnClickCódigo: procedure TForm1.Button11Click(Sender: TObject); begin conf_canc_generico(datamodule1.query2,false); end;

Objetivo: Executar o comando cancelupdates na query2, através da funçãoconf_canc_generico, onde a transação pendente será cancelada, retornando aquery2 ao estado inicial.

No exemplo1 executaríamos o comando ROLLBACK, só que conforme explicadono código para o Button10, apenas a transação pendente da query2 será cancelada,e não todas as do banco de dados Oracle.

NO TA: Uma vez expostas as principais diferenças entre o exemplo1 e o corrente,nas próximas etapas, será abordada somente a funcionalidade de cada evento ge-rado para seu respectivo componente.

���!����"�,�;�&���$�H�����������#�!��� �����I

TabSheet3 Responsável por incluir, alterar e excluir um departamento.

Evento: OnShow Código: procedure TForm1.TabSheet2Show(Sender: TObject); begin panel2.enabled:= false; limpa_var_generico(dbcodcargo,dbdesccargo); end;

Objetivo: Exibir todas as colunas da tabela DEPTO2 e seu respectivo conteúdo,limpar a propriedade text dos componentes, alterar o valor da propriedade enabled

Page 133: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 135

para false no panel3, evitando que, antes de ser pressionado um dos botões de In-cluir ou Alterar, informações sejam inseridas.

1 – DbGrid3Exibir informações da tabela DEPTO2, através da query3.Evento: Não existe.

2 – DbCodDepArmazenar em memória, até ser transferida para o banco de dados, a coluna docódigo do departamento a ser inserido ou alterado.Evento: Não existe.

3 – EdtDescDepArmazenar em memória, até ser transferida para o banco de dados, a coluna dadescrição do departamento a ser inserido ou alterado.Evento: Não existe.

4 – Button13A rotina inclusão deve possibilitar que a tabsheet3 fique em condições de inseririnformações nos componentes dbcoddep e dbdescdep permitindo a transferênciaposterior para o banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button13Click(Sender: TObject); begin insert_generico(panel3,datamodule1.query3,dbmatric); limpa_var_generico(dbcoddep, dbdescdep); dbcoddep.setfocus; end;

Objetivo: Alterar o valor da propriedade enabled para true no panel3, onde pode-rão ser inseridas informações nos componentes, e colocar a query2 no modo deinserção, através da função insert_generico.

4 – Button14Através da rotina de exclusão, será permitido apagar um departamento e seu res-pectivo relacionamento através da constraint criada.

Evento: OnClickCódigo:

procedure TForm1.Button14Click(Sender: TObject); begin datamodule1.query3.delete; end;

Page 134: Delphi 6 com Oracle

136 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Objetivo: Excluir os registros nas tabelas DEPTO2 e EMPXDEP2, utilizando di-retamente o evento delete da query3.

4 – Button15Na rotina de alteração, devemos colocar a tabsheet3 em condições de alterar asinformações contidas nos componentes dbcoddep e dbdescdep.

Evento: OnClickCódigo: procedure TForm1.Button15Click(Sender: TObject); begin limpa_var_generico(dbcoddep,dbdescdep); edit_generico(panel3,datamodule1.query3,dbcoddep,dbdescdep); end;

Objetivo: Colocar a query3 em modo de alteração, através da função edit_generico,para que o conteúdo do registro atual possa ser modificado, já que estamos utili-zando o registro corrente da tabela.

4 – Button16Esta rotina deve tornar permanente a atualização pendente na query3, transferindoentão o registro para a tabela DEPTO2.

Evento: OnClickCódigo: procedure TForm1.Button16Click(Sender: TObject); begin conf_canc_generico(datamodule1.query3,true); end;

Objetivo: Executar o comando applyupdates na query3, através da funçãoconf_canc_generico, tornando permanente no banco de dados a transação pendentena query3, inserido ou alterado, efetivamente na tabela CARGOS2, um registro.

4 – Button17Esta rotina, ao contrário da anterior, deve cancelar a atualização pendente naquery3, retornando ao estado inicial.

Evento: OnClickCódigo: procedure TForm1.Button17Click(Sender: TObject); begin conf_canc_generico(datamodule1.query3,false); end;

Page 135: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 137

Objetivo: Executar o comando cancelupdates na query3, através da funçãoconf_canc_generico, onde a transação pendente será cancelada, retornando aquery3 ao estado inicial.

���!��$�"�,�;�&��� �H������������������:���I

TabSheet1 Responsável por incluir, alterar e excluir um funcionário.

Evento: OnShowCódigo: procedure TForm1.tabsheet1Show(Sender: TObject); begin panel1.enabled:= false; limpa_var_empregados; end;

Objetivo: Exibir todas as linhas da tabela EMPREGADOS2, suas colunas e seu res-pectivo conteúdo, limpar a propriedade text dos componentes, o valor da propriedadeenabled devendo ser alterado para false no panel1, evitando que informações sejaminseridas sem que antes um dos botões de Incluir ou Alterar seja pressionado.

1 – DbGrid1Exibir informações da tabela EMPREGADOS2, através da query1.Evento: Não existe.

2 – DBMatricArmazenar em memória a coluna do número da matrícula do funcionário a ser in-serida ou alterada até que possa ser transferida para o banco de dados.Evento: Não existe.

3 – DBNomeArmazenar em memória a coluna do nome do funcionário a ser inserido ou alterado.Evento: Não existe.

4 – DBDataArmazenar em memória a coluna da data de aniversário do funcionário a ser inse-rido ou alterado.Evento: Não existe.

5 – DBEnderArmazenar em memória a coluna do endereço do funcionário a ser inserido oualterado.Evento: Não existe.

Page 136: Delphi 6 com Oracle

138 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

6 – DBSalarioArmazenar em memória a coluna do salário do funcionário a ser inserido ou alterado.Evento: Não existe.

7 – Button1A rotina a seguir deve ser capaz de colocar a tabsheet1 em condições de inseririnformações em seus componentes, para posterior transferência para o banco dedados.

Evento: OnClickCódigo: procedure TForm1.Button7Click(Sender: TObject); begin insert_generico(panel1,datamodule1.query1,dbmatric); limpa_var_empregados; dbmatric.setfocus; end;

Objetivo: O valor da propriedade enabled deve ser modificado para true no panel1,permitindo que informações sejam inseridas nos componentes, e colocar a query1,através da função insert_generico, no modo de inserção.

7 – Button2A rotina de exclusão permite que um funcionário e seus respectivos relacionamen-tos sejam apagados, através da constraint criada.

Evento: OnClickCódigo: procedure TForm1.Button2Click(Sender: TObject); begin datamodule1.query1.delete; end;

Objetivo: Apagar os registros nas tabelas EMPREGADOS2, EMPXCARGO2 eEMPXDEP2, através do evento delete da query2.

7 – Button3A rotina de alteração permite a tabsheet1 alterar as informações contidas em seuscomponentes.

Evento: OnClickCódigo: procedure TForm1.Button3Click(Sender: TObject); begin limpa_var_empregados;

Page 137: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 139

edit_generico(panel1,datamodule1.query1,dbmatric,dbnome); end;

Objetivo: Alterar o estado da query1, para que o conteúdo do registro corrente pos-sa ser modificado.

7 – Button4Esta rotina deve tornar permanente a atualização pendente na query1, onde o re-gistro deve ser transferido para a tabela EMPREGADOS2.

Evento: OnClickCódigo: procedure TForm1.Button10Click(Sender: TObject); begin conf_canc_generico(datamodule1.query1,true); end;

Objetivo: Executar o comando applyupdates na query1, através da funçãoconf_canc_generico, onde será transportada para a tabela EMPREGADOS2 nobanco de dados a transação pendente na query1.

7 – Button6A rotina de cancelamento deve retornar a query1 ao seu estado inicial.

Evento: OnClickCódigo: procedure TForm1.Button11Click(Sender: TObject); begin conf_canc_generico(datamodule1.query1,false); end;

Objetivo: Executar a função conf_canc_generico, onde a transação pendente serácancelada.

���!��%�"�,�;�&���(�H������������������� ����������� !��������������I

TabSheet5Responsável por incluir, alterar e excluir um relacionamento entre um funcionárioe um departamento.

Evento: OnShowCódigo: procedure TForm1.TabSheet5Show(Sender: TObject); begin

Page 138: Delphi 6 com Oracle

140 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

limpa_var_generico(dbmatric2,dbcodcargo2); panel5.enabled:= false; executa_refresh(datamodule1.query5); end;

Objetivo: Exibir todas as colunas da tabela EMPXCARGO2 e seu respectivo con-teúdo, limpar a propriedade text dos componentes, modificar o valor da proprieda-de enabled para false no panel5, assegurando que, antes de ser pressionado um dosbotões de Incluir ou Alterar, informações sejam inseridas.

1 – DbGrid5Exibir informações da tabela EMPXCARGO2, através da query5.Evento: Não existe.

2 – DbMatric2Armazenar em memória, até ser transferida para o banco de dados, a coluna damatrícula do funcionário a ser inserido ou alterado.Evento: Não existe.

3 – DbCodcargo2Armazenar em memória, até ser transferida para o banco de dados, a coluna docódigo do cargo a ser inserido ou alterado.Evento: Não existe.

4 – Button21A rotina inclusão deve possibilitar a tabsheet5 ficar em condições de inserir infor-mações nos componentes dbmatric2 e dbcodcargo2 permitindo a transferênciaposterior para o banco de dados.

Evento: OnClickCódigo:

procedure TForm1.Button21Click(Sender: TObject); begin insert_generico(panel5,datamodule1.query5,dbmatric2); limpa_var_generico(dbmatric2,dbcodcargo2); dbmatric2.setfocus; end;

Objetivo: O valor da propriedade enabled deve ser modificado para true no panel3,onde poderão ser inseridas informações nos componentes, e colocar a query5 nomodo de inserção, através da função insert_generico.

Page 139: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 141

4 – Button22A seguir, através da rotina de exclusão, será permitido apagar um relacionamentoentre um funcionário e seu respectivo cargo, através da constraint criada.

Evento: OnClickCódigo: procedure TForm1.Button14Click(Sender: TObject); begin datamodule1.query5.delete; end;

Objetivo: Apagar os registros na tabela EMPXCARGO2, através do evento deleteda query5.

4 – Button23Na rotina de alteração será possível a tabsheet5 alterar as informações contidas noscomponentes dbmatric2 e dbcargo2.

Evento: OnClickCódigo: procedure TForm1.Button23Click(Sender: TObject); begin limpa_var_generico(dbmatric2,dbcodcargo2); edit_generico(panel5,datamodule1.query5,dbmatric2,dbcodcargo2); end;

Objetivo: Colocar a query5 em modo de alteração, através da função edit_generico,para que o conteúdo do registro corrente possa ser modificado.

4 – Button24A rotina deve tornar permanente a atualização pendente na query5, transferindoentão o registro para a tabela EMPXCARGO2.

Evento: OnClickCódigo: procedure TForm1.Button16Click(Sender: TObject); begin conf_canc_generico(datamodule1.query5,true); end;

Objetivo: Executar o comando applyupdates na query5, através da funçãoconf_canc_generico, tornando permanente no banco de dados a transação pendentena query5.

Page 140: Delphi 6 com Oracle

142 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

4 – Button25Ao contrário da anterior, esta rotina deve ser capaz de cancelar a atualização pen-dente na query5.

Evento: OnClickCódigo: procedure TForm1.Button17Click(Sender: TObject); begin conf_canc_generico(datamodule1.query5,false); end;

Objetivo: O comando cancelupdates será executado na query5, através da funçãoconf_canc_generico, onde a transação pendente será cancelada, retornando aquery5 ao estado inicial.

���!��(�"�,�;�&���+�H������������������� ����������� !���������#�!��� �����I

TabSheet6Responsável por incluir, alterar e excluir um relacionamento entre um funcionárioe um departamento.

Evento: OnShowCódigo: procedure TForm1.TabSheet6Show(Sender: TObject); begin limpa_var_generico(dbmatric3,dbcoddep2); panel6.enabled:= false; executa_refresh(datamodule1.query4); end;

Objetivo: Todas as colunas da tabela EMPXDEPTO2 e seu respectivo conteúdoserão exibidos, limpar a propriedade text dos componentes, alterar o valor da pro-priedade enabled para false no panel6, evitando que, antes de ser pressionado umdos botões de Incluir ou Alterar, informações sejam inseridas.

1 – DbGrid6Exibir informações da tabela EMPXDEPTO2, através da query4.Evento: Não existe.

2 – DbMatric3Armazenar em memória a coluna da matrícula do funcionário a ser inserido oualterado, até ser transferida para o banco de dados.Evento: Não existe.

Page 141: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 143

3 – EdtCodDep2Armazenar em memória, até ser transferida para o banco de dados, a coluna docódigo do departamento a ser inserido ou alterado.Evento: Não existe.

4 – Button27A inclusão, através da rotina a seguir, deve possibilitar que a tabsheet6 fique emcondições de inserir informações em seus componentes, permitindo, posterior-mente, a transferência para o banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button27Click(Sender: TObject); begin insert_generico(panel6,datamodule1.query4,dbmatric3); limpa_var_generico(dbmatric3,dbcoddep2); dbmatric3.setfocus; end;

Objetivo: Através da função insert_generico, será permitido colocar a query4 nomodo de inserção, onde poderão ser inseridas informações nos componentesdbmatric3 e dbcoddep2. Alterar o valor da propriedade enabled para true no pa-nel6.

4 – Button28A rotina de exclusão permite apagar um relacionamento entre um funcionário e umdepartamento, através da constraint criada.

Evento: OnClickCódigo: procedure TForm1.Button14Click(Sender: TObject); begin datamodule1.query4.delete; end;

Objetivo: Excluir o registro na tabela EMPXDEP2, utilizando diretamente o eventodelete da query4.

4 – Button29Devemos colocar a tabsheet6, através da rotina a seguir, em condições de alterar asinformações contidas nos componentes dbmatric3 e dbcoddep2.

Evento: OnClickCódigo:

Page 142: Delphi 6 com Oracle

144 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

procedure TForm1.Button29Click(Sender: TObject); begin limpa_var_generico(dbmatric3,dbcoddep2); edit_generico(panel6,datamodule1.query4,dbmatric3,dbcoddep2); end;

Objetivo: Colocar a query4 em modo de alteração, através da função edit_generico,onde o conteúdo do registro corrente será modificado.

4 – Button30Esta rotina deve tornar permanente a atualização pendente na query4, transferindoentão o registro para a tabela EMPXDEPTO2.

Evento: OnClickCódigo: procedure TForm1.Button30Click(Sender: TObject); begin conf_canc_generico(datamodule1.query4,true); end;

Objetivo: Através da função conf_canc_generico, executar o comando applyupda-tes na query6, tornando permanente no banco de dados a transação pendente naquery4.

4 – Button31Esta rotina, ao contrário da anterior, deve cancelar a atualização pendente naquery6.

Evento: OnClickCódigo: procedure TForm1.Button17Click(Sender: TObject); begin conf_canc_generico(datamodule1.query4,false); end;

Objetivo: Executar a função conf_canc_generico, onde a transação pendente serácancelada, retornando a query6 ao estado inicial.

���!��+�"�,�;�&���%�H��������������������:�������������IAntes de iniciar a explicação do código gerado para esse formulário de consulta,quero deixar claro que, por fugir ao escopo do que será exposto, não irei comentaro código criado em componente TRadioButton, pois sua finalidade é, única e ex-clusivamente, a de controlar a entrada em cada um deles.

Page 143: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 145

TabSheet4Responsável por consultar um funcionário, seu respectivo cargo e departamento.

Evento: OnShowCódigo: procedure TForm1.tabsheet4Show(Sender: TObject); begin limpa_var_consulta; end;

Objetivo: Limpar a propriedade text de todos os componentes da tabsheet4.

20 – Button22Gerar a consulta para um funcionário, em função dos valores informados nos com-ponentes contidos na tabsheet4.

Evento: OnClickCódigo: procedure TForm1.Button19Click(Sender: TObject); var stringsql: string; lescolheu_sal: boolean; ind: integer; begin ind:= 0; lescolheu_sal:= false;

pselect:= 'SELECT Empregados2.MATRICULA, Empregados2.Nome, '+ ' Empregados2.SALARIO,'+ ' Empregados2.NASCIM, Cargos2.DESCRICAO, '+ ' Depto2.DESCRICAO ';

pfrom:= ' FROM EMPREGADOS2 Empregados2, EMPXCARGO2 Empxcargo2, '+ ' EMPXDEP2 Empxdep2,'+ ' CARGOS2 Cargos2, DEPTO2 Depto2 ';

pwhere:= ' WHERE (Empregados2.MATRICULA = Empxcargo2.MATRICULA) '+ ' AND (Cargos2.CODCARGO = Empxcargo2.CODCARGO) '+ ' AND (Empregados2.MATRICULA = Empxdep2.MATRICULA) '+ ' AND (Depto2.CODDEP = Empxdep2.CODDEP) '; pgroup:= '';

if rbmaisal.checked then begin pselect:= 'SELECT MAX(Empregados2.SALARIO)'; lescolheu_sal:= true; end;

if rbmensal.checked then begin pselect:= 'SELECT MIN(Empregados2.SALARIO)'; lescolheu_sal:= true;

Page 144: Delphi 6 com Oracle

146 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

end;

if rbmedsal.checked then begin pselect:= 'SELECT AVG(Empregados2.SALARIO)'; lescolheu_sal:= true; end;

if lescolheu_sal then begin pselect:= pselect + ',Depto2.DESCRICAO '; pgroup:= 'GROUP BY Depto2.DESCRICAO'; end;

with datamodule1.query6 do begin params.clear; sql.clear;

if rbsldepto.checked then begin pwhere:= pwhere+' AND (Depto2.CODDEP =:departamento) '; params.add; params[ind].name:= 'departamento'; params[ind].asstring:= edtdepto2.text; ind:= ind+1; end;

if rbslcargos.checked then begin pwhere:= pwhere+' AND (Cargos2.CODCARGO =:cargo) '; params.add; params[ind].name:= 'cargo'; params[ind].asstring:= edtcargos2.text; ind:=ind+1; end;

if not lescolheu_sal then begin if rbslfunci.checked then begin pwhere:= pwhere+' AND (Empregados2.MATRICULA =:matricula) '; params.add; params[ind].name:= 'matricula'; params[ind].asstring:= edtmatric2.text; ind:=ind+1; end;

if rbdtcontrat.checked then begin pwhere:= pwhere+' AND (Empregados2.NASCIM =:nascimento) '; params.add; params[ind].name:= 'nascimento'; params[ind].asstring:= mskdata2.text; end; end;

stringsql:= pselect+pfrom+pwhere+pgroup; sql.add(stringsql); open; end; end;

Page 145: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via BDE • 147

Objetivo: Criar uma consulta, utilizando as tabelas FUNCIONARIOS, DEPTO,CARGOS, EMPXDEP, EMPXCARGO, através de 4 variáveis, que irão compor ocomando SELECT. Sendo elas:

• pselect – Escolhe os campos que serão exibidos pela consulta;• pfrom – Seleciona as tabelas da consulta;• pwhere – Seleciona a condição da consulta;• pgroup – Agrupa os dados, se necessário, da consulta.

Cada variável recebe um valor inicial, podendo ser inteiramente modificado ouconcatenado com outro, variando conforme a escolha de alguma opção da tela deconsulta. Ao final, seus valores serão somados em uma única variável: stringsql.

O bservação: A consulta é gerada através de um join realizado nas cinco tabelascriadas, onde obteremos de cada uma a informação necessária. A figura 9.119 nosmostra o relacionamento de cada tabela:

Obtém o nome do departamento em Obtém o nome do cargo deque cada funcionário trabalha. cada funcionário da empresa.

������. � .

Page 146: Delphi 6 com Oracle

148

10. Conexão com o Banco de Dados Oraclevia dbExpress

�� !��������6���������������C��O Delphi incluiu na versão 6 a aba dbExpress, que traz componentes responsáveispela conexão com o banco de dados Oracle de uma forma mais rápida.

Ao utilizarmos os componentes localizados nessa aba, nossas aplicações se torna-rão portáveis para o Kylix, o que não acontece ao utilizarmos o ADO, que é umpadrão proprietário do Windows.

A figura 10.1 nos mostra, utilizando os principais componentes, como o Delphitrata o acesso ao banco de dados.

,�20����������O componente TSQLConnection nos permite estabelecer uma conexão com o ban-co de dados Oracle através do driver dbExpress e de dois arquivos .ini(dbxdrivers.ini e dbxconnections.ini).

O primeiro, dbxdrivers.ini, contém os tipos de drivers instalados (Oracle, DB2,MySql, etc.) e, para cada driver, as bibliotecas (DLLs) com as configurações pa-drão com os parâmetros de conexão.

O segundo, dbxconnections.ini, contém um conjunto de configurações (nome esenha do usuário, instância do banco, etc.) para conexão com os diversos tipos debancos de dados.

Page 147: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 149

SQLConnection

DataSource

SQLClientDataSet

SQLDataSet SQLQuery

������ G �

Adiante estão listadas as principais propriedades para estabelecermos uma conexãocom o banco de dados Oracle.

Nome: ConnectedTipo: BooleanDescrição: Indica se foi estabelecida uma conexão com o banco de dados Oracle.

Nome: ConnectionNameTipo: StringDescrição: Especifica qual a configuração, contida no arquivo dbconnections.ini,a ser utilizada para conexão com o banco de dados.

Ao alterá-la, automaticamente as propriedades drivername e params serão modifi-cadas conforme configuração do arquivo dbconnections.ini.

Nome: DriverNameTipo: StringDescrição: Especifica qual o driver, contido no arquivo dbxdriver.ini, a ser utiliza-do para conexão com o banco de dados.

Page 148: Delphi 6 com Oracle

150 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Essa propriedade é automaticamente alterada quando modificamos a proprieda-de ConnectionName.

Nome: LoginPromptTipo: BooleanDescrição: Especifica se a caixa de login será exibida quando o aplicativo tentarum conexão no banco de dados Oracle.

Nome: ParamsTipo: TStringsDescrição: Especifica os parâmetros necessários para a conexão como o banco dedados.

,�20#������O TSQLDataSet é um componente de uso geral, ou seja, tanto pode ser utilizadopara executar uma query, uma storage procedure ou uma table.

Diferente de outros datasets, TSQLDataSet é um componente unidirecional, ouseja, não bufferiza diversos registros na memória. Em função disso, somente osmétodos First e Next poderão ser utilizados.

A seguir as principais propriedades deste componente.

Nome: CommandTextTipo: StringDescrição: Depende do valor da propriedade CommandType:

– ctQuery – CommandText será o comando SQL a ser executado;

– ctStoredProc – CommandText será o nome da Storage Procedure a ser executada;

– ctTable – CommandText será o nome da tabela no servidor.

Nome: CommandTypeTipo: TSQLCommandTypeDescrição: indicará o tipo de comando que estará contido na propriedade Com-mandText.

Nome: DataSourceTipo: TDataSourceDescrição: Especifica o componente TDataSource a ser utilizado.

Page 149: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 151

Nome: SQ LConnectionTipo: TSQLConnectionDescrição: Especifica o componente TSQLConnection a ser utilizado, permitindoassim a conexão com o banco de dados.

A seguir os principais métodos deste componente.

Nome: CloseDescrição: Altera o valor da propriedade Active para false.

Nome: ExecSqlDescrição: Executa uma declaração SQL que não retorna um conjunto de resulta-dos.

Nome: O penDescrição: Altera o valor da propriedade Active para true, executando uma decla-ração SQL que retorne um conjunto de resultados.

,�202���O componente permite que o aplicativo submeta declarações SQL para o banco dedados Oracle, através do componente TSQLConnection.

Assim como o TSQLDataSet, TSQLQuery é um componente unidirecional, ouseja, não bufferiza o resultado dos comandos SQL (através do comando SELECT)na memória. Em função disso, somente os métodos First e Next poderão ser utili-zados. Dessa forma, os registros jamais poderão ser visualizados através deDBGrids, etc. A seguir as principais propriedades deste componente.

Nome: DataSourceTipo: TDataSourceDescrição: Especifica o componente TDataSource a ser utilizado.

Nome: SQ LTipo: StringDescrição: Armazena uma declaração SQL.

Nome: SQ LConnectionTipo: TSQLConnectionDescrição: Especifica o componente TSQLConnection a ser utilizado, permitindoassim a conexão com o banco de dados.

Page 150: Delphi 6 com Oracle

152 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

A seguir os principais métodos deste componente.

Nome: CloseDescrição: Altera o valor da propriedade Active para false.

Nome: ExecSqlDescrição: Executa uma declaração SQL que não retorna um conjunto de resulta-dos.

Nome: O penDescrição: Altera o valor da propriedade Active para true, executando uma decla-ração SQL que retorne um conjunto de resultados.

,�20������#������O componente TSQLClientDataSet talvez seja o componente mais versátil da abadbExpress. Ele incorpora as propriedades do componente TSQLConnection, (nãoprecisa do mesmo para se conectar ao banco de dados) e do componenteTSQLDataSet (é capaz de executar comandos SQL, storage procedures e tables),além de bufferizar resultados de cláusulas SQL (registros) na memória. Atravésdesse componente o resultado de nossas querys poderá, agora, ser visualizadoatravés de um DBGrid, etc.

Tal versatilidade, porém, tem um custo: em função da bufferização, esse compo-nente torna a máquina cliente mais lenta, perdendo em performance para o compo-nente TSQLDataSet.

Principais propriedades:

Nome: CommandTextTipo: StringDescrição: Depende do valor da propriedade CommandType:

– ctQuery – CommandText será o comando SQL a ser executado;

– ctStoredProc – CommandText será o nome da Storage Procedure a ser executada;

– ctTable – CommandText será o nome da tabela no servidor.

Nome: CommandTypeTipo: TSQLCommandTypeDescrição: Indicará o tipo de comando que estará contido na propriedadeCommandText.

Page 151: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 153

Nome: ConnectionNameTipo: StringDescrição: Especifica qual a configuração, contida no arquivo dbconnections.ini,a ser utilizada para conexão com o banco de dados.

Nome: DBConnectionTipo: TSQLConnectionDescrição: Especifica o componente TSQLConnection a ser utilizado, permitindoassim a conexão com o banco de dados.

Ao alterá-la, automaticamente a propriedade connectionName será modificada,onde seu valor ficará em branco, pois já estamos utilizando as configurações docomponente SQLConnection.

,#��������Permite estabelecer uma conexão entre um ou mais componentes Data Controls(dbgrids, dbedit, etc.) e em cada componente TSQLQuery, TSQLDataSet ouTSQLClientDataSet. A seguir, é mostrada a propriedade mais importante dessecomponente.

Nome: DataSetTipo:TDataSetDescrição: Especifica o dataset do qual o componente obtém seus dados.

�C� !���#��!&�F�;�C!��� ��� �/����As tabelas a serem criadas no banco de dados, conforme exemplos anteriores, utili-zarão a constraint FOREIGN KEY com a cláusula DELETE CASCADE. Dessaforma, toda a integridade de dados será controlada pelo banco de dados Oracle.

� Criando a tabela de empregados:

SQL > CREATE TABLE EMPREGADOS4 2 (MATRICULA VARCHAR2(5) NOT NULL, 3 NOME VARCHAR2(30) NOT NULL, 4 SALARIO NUMBER NULL, 5 ENDERECO VARCHAR2(50) NULL, 6 CONSTRAINT PK_MATRIC PRIMARY KEY (MATRICULA));

Page 152: Delphi 6 com Oracle

154 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

� Criando a tabela de cargos:

SQL > CREATE TABLE CARGOS4 2 (CODCARGO VARCHAR2(3) NOT NULL, 3 DESCRICAO VARCHAR2(25) NULL, 4 CONSTRAINT PK_CODCARGO4 PRIMARY KEY (CODCARGO));

� Criando a tabela de relacionamentos de empregados com cargos:

SQL > CREATE TABLE EMPXCARGO4 2 (MATRICULA VARCHAR2(5) NOT NULL, 3 CODCARGO VARCHAR2(3) NOT NULL, 4 CONSTRAINT FK_CODCARGO4 FOREIGN KEY (CODCARGO) 5 REFERENCES CARGOS4(CODCARGO) ON DELETE CASCADE, 6 CONSTRAINT FK_MATRIC FOREIGN KEY (MATRICULA) 7 REFERENCES EMPREGADOS4(MATRICULA) ON DELETECASCADE);

� Criando a tabela de departamentos:

SQL > CREATE TABLE DEPTO4 2 (CODDEP VARCHAR2(3) NOT NULL, 3 DESCRICAO VARCHAR2(30) NULL, 4 CONSTRAINT PK_CODDEP4 PRIMARY KEY (CODDEP));

� Criando a tabela de relacionamentos de empregados com departamentos:

SQL > CREATE TABLE EMPXDEP4 2 (MATRICULA VARCHAR2(5) NOT NULL, 3 CODDEP VARCHAR2(3) NOT NULL, 4 CONSTRAINT FK_MATRI4 FOREIGN KEY (MATRICULA) 5 REFERENCES EMPREGADOS4(MATRICULA) ON DELETECASCADE, 6 CONSTRAINT FK_CODDEP4 FOREIGN KEY (CODDEP) 7 REFERENCES DEPTO4(CODDEP) ON DELETE CASCADE);

Após criarmos as tabelas da nossa aplicação, devemos então executar o Delphi. Aaplicação será desenvolvida, conforme os exemplo anteriores, em duas partes:

Parte 1 – Criação dos componentes necessários;Parte 2 – Explicação do código gerado para cada componente criado.

Page 153: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 155

5���� �"�������������� !��������������:���

���!�� �"������������ �����#��� �����

Um novo Datamodule deve ser adicionado ao projeto. Vá em File->New->DataModule. Os seguintes valores deverão ser modificados:

������ G ��

O DataModule deverá ser salvo como udmexemplo4.pas

���!����"�8���������%��� !������������;���;�C!������#��� �����Conforme Figura 10.3, 4 componentes deverão ser adicionados:

������ G �$

1

2

3

4

Page 154: Delphi 6 com Oracle

156 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Os seguintes valores deverão ser modificados:

1 – TSQLConnection

������ G �%

2 – TClientDataSet 3 – TSQLQuery

��������������� ��� � G�( ������������ G �+

Page 155: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 157

4 – TDataSource

������ G �-

���!��$�"�������>������ ��:���!����!��>���!������������������� !�������Uma vez criados os componentes no TDataModule, deveremos, então, criar o pa-gecontrol, assim como 6 tabsheets que deverão ter sua propriedade Caption modi-ficadas para Empregados, Cargos, Departamentos, Empregados X Cargos, Empre-gados X Departamentos e Consulta conforme mostra a figura 10.8.

������ G ��

Pagecontrol

Tabsheet1

Tabsheet2Tabsheet3

Tabsheet4 Tabsheet5

Tabsheet6

Page 156: Delphi 6 com Oracle

158 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

���!��$� �"������������� !�������������;�&���

������ G �.

Não comentarei os label’s criados em nenhuma das etapas, pois a única proprieda-de que iremos setar de cada um é o caption, que deve ser a mesma das figurasmostradas. Os seguintes valores deverão ser modificados:

Tabsheet1

1 23

4

5

6

Page 157: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 159

1 – TDBGrid 3 – TEdit

������ G � G ������ G � �

2 – TEdit 4 – TEdit

������ G � �������������� G � $

Page 158: Delphi 6 com Oracle

160 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

5 – TEdit

������ G � %

6 – TButtons

Nos componentes TButtons criados, deveremos modificar a propriedade name paraButton1, Button2,...,Button7, seguindo a ordem da esquerda para a direita. A pro-priedade caption de cada um deve ser alterada conforme a figura 10.9.

���!��$���"������������� !�������������;�&����

4������ G � (

Tabsheet2

12

3

Page 159: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 161

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TEdit

�������������������� G� + ������ G � �

2 – TEdit

������ ������ G � -

Page 160: Delphi 6 com Oracle

162 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

4 – TButtons

Nos componentes TButtons criados, deveremos alterar a propriedade name paraButton7, Button8,...,Button14, seguindo a ordem da esquerda para a direita. A pro-priedade caption de cada um deve ser alterada conforme a figura 10.15.

���!��$�$�"������������� !�������������;�&���$

������ G � .

32

1

Tabsheet3

4

Page 161: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 163

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TEdit

������ G ��G ������������� ��� � G���

2 – TEdit

������������������ G��

Page 162: Delphi 6 com Oracle

164 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

4 – TButtons

Nos componentes TButtons criados deveremos alterar a propriedade name paraButton15, Button16,...,Button21, seguindo a ordem da esquerda para a direita. Apropriedade caption de cada um deve ser alterada conforme a figura 10.19.

���!��$�%�"������������� !�������������;�&���%

������ G ��$

3

2

1

Tabsheet4

4

Page 163: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 165

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TEdit

������ G ��% ������ G ��+

2 – TEdit

��������������� ��� � G��(

Page 164: Delphi 6 com Oracle

166 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

4 – TButtons

Nos componentes TButtons criados, deveremos alterar a propriedade name paraButton22, Button23,...,Button28, seguindo a ordem da esquerda para a direita. Apropriedade caption de cada um deve ser alterada conforme a figura 10.23.

���!��$�(�"������������� !�������������;�&���(

������ G ��-

4

3

2

1

Tabsheet5

Page 165: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 167

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TEdit

������������������ G��� ������������ � G�$G

2 – TEdit

������ G ��.

Page 166: Delphi 6 com Oracle

168 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

4 – TButtons

Nos componentes TButtons criados, deveremos alterar a propriedade name paraButton29, Button30,...,Button35, seguindo a ordem da esquerda para a direita. Apropriedade caption de cada um deve ser alterada conforme a figura 10.27.

���!��$�+�"������������� !�������������;�&���+

������ G �$

Tabsheet6

1

2 3

4 5

67

8

910

11 12 13 14

1516 17 18

19

Page 167: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 169

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TRadioButton

��������������� ��� � G�$� ����������� ��� � G�$%

2 – TGroupBox 4 – TRadioButton

���������������� G�$$ ���������� � G�$(

Page 168: Delphi 6 com Oracle

170 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

5 – TEdit 7 – TRadioButton

������ G �$+ ��� ���������� � G�$�

6 – TGroupBox 8 – TRadioButton

������ G �$- ���� ����� ���������� � G�$.

Page 169: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 171

9 – TRadioButton 11 – TGroupBox

���������������� G�%G ��� ������ ���� G �%�

10 – TButton 12 – TRadioButton

������������� ��� � G�% ���������� � G�%$

Page 170: Delphi 6 com Oracle

172 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

13 – TRadioButton 15 – TGroupBox

���������������� G�%% ���������� � G�%+

14 – TEdit 16 – TRadioButton

������������������ G�%( ��� ����������� ��� � G�%-

Page 171: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 173

17 – TRadioButton 18 – TEdit

��������������� ��� � G�%� ������������ G �%.

19 – TButtons

Nos componentes TButtons criados, deveremos alterar a propriedade name paraButton36 e Button37, seguindo a ordem da esquerda para a direita. A propriedadecaption de cada um deve ser alterada conforme a figura 10.31.

5������"��C!������������?�����������!��������� !������������Antes de iniciarmos a explicação sobre o funcionamento de cada tabsheet, deve-mos criar uma variável global do tipo TTransactiondesc, que será responsável poridentificar a transação corrente em nossa aplicação:

...var

Form1: TForm1; pinclui: boolean; td: ttransactiondesc;

implementation....

Variável global

Page 172: Delphi 6 com Oracle

174 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Se essa variável não for criada, todo comando INSERT, UPDATE ou DELETEque for executado na propriedade SQL do componente TSQLQuery, automatica-mente será confirmada no bando de dados Oracle, não permitindo dessa forma ocancelamento de qualquer transação.

Em seguida, algumas procedures e funções de uso geral do projeto devem ser cria-das. A procedure a seguir é responsável por limpar os componentes contidos emcada Tabsheet:

procedure TForm1.limpacomponentes;var ind: integer;begin for ind:= 0 to ComponentCount-1 do begin if components[ind] is tedit then (components[ind] as tedit).clear; end;end;

Será necessário criarmos uma procedure que inicie uma transação em nossa aplica-ção.procedure TForm1.iniciatransacao;begin with datamodule2.sqlconnection1 do begin if not InTransaction then begin td.transactionid:= 1; td.isolationlevel:= xilREADCOMMITTED; starttransaction(td); end; end;end;

A procedure anterior verifica se existe alguma transação em aberto; caso não exis-ta, inicia uma nova com a variável global td criada anteriormente.

Uma vez que todas as instruções SQL de inclusão, exclusão e alteração serão exe-cutadas na SQLQuery1, a procedure a seguir evita a replicação de código em nossoprojeto, bastando para isso que passemos como parâmetro a instrução SQL deseja-da.

procedure TForm1.executasql(stringsql: string);begin with datamodule2.SQLQuery1 do begin close; sql.clear; sql.add(stringsql); execsql; end;end;

Page 173: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 175

Para que toda inclusão, alteração e exclusão de registros efetuada no banco de da-dos reflita nos dbgrids do projeto, é necessário fechar e abrir, logo em seguida, aSQLquery associada a ele. As procedures executasql2 e executarefresh listadaslogo adiante serão responsáveis por essa tarefa.

procedure TForm1.executasql2(stringsql: string);begin with datamodule2.SQLClientDataSet1 do begin close; commandtext:= stringsql; open; end;end;

procedure TForm1.executarefresh;begin with pagecontrol1 do begin if activepage = tabsheet1 then executasql2('select * from empregados4 order by 1')

else if activepage = tabsheet2 then executasql2('select * from cargos4 order by 1')

else if activepage = tabsheet3 then executasql2('select * from depto4 order by 1')

else if activepage = tabsheet4 then executasql2('select empregados4.matricula, empregados4.nome, '+ ' cargos4.codcargo, cargos4.descricao '+ 'from empregados4 empregados4, cargos4 cargos4, empxcargo4 empxcargo4 '+ 'where empregados4.matricula = empxcargo4.matricula and '+ ' cargos4.codcargo = empxcargo4.codcargo ')

else if activepage = tabsheet5 then executasql2('select empregados4.matricula, empregados4.nome, '+ 'depto4.coddep, depto4.descricao '+ 'from empregados4 empregados4, depto4 depto4, empxdep4 empxdep4 '+ 'where empregados4.matricula = empxdep4.matricula and '+ ' depto4.coddep = empxdep4.coddep ')

else if activepage = tabsheet6 then datamodule2.SQLClientDataSet1.Close;

end;end;

A seguir, serão explicados, através de etapas, o ‘funcionamento’ de cada tabsheet,assim como os eventos referentes ao formulário, pagecontrol e a cada botão.

���!�� �"��� ��:���!����!���H�� I

É o formulário do nosso projeto, onde estão contidos todos os componentes.

Page 174: Delphi 6 com Oracle

176 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Evento: OnActivateCódigo: procedure TForm1.FormActivate(Sender: TObject); var stringsql: string; begin pagecontrol1.activepage:= tabsheet1; stringsql:= 'select * from empregados4'; executasql2(stringsql); limpacomponentes; pinclui:= false; end;

Objetivo: Inicializar nosso projeto, definindo a tabsheet1 como ativa, limpando oscomponentes e executando o comando SQL para exibir os dados da tabela EM-PREGADOS4.

���!����"�5���������É o componente que contém todas as tabsheets de nosso projeto.

Evento: OnChangeCódigo: procedure TForm1.PageControl1Change(Sender: TObject); begin executarefresh; limpacomponentes; end;

Objetivo: Verifica qual a tabsheet que está ativa, atualizando os dados no dbgridcorrente, através da procedure executarefresh, e em seguida limpa os componentesda tela.

���!��$�"�,�;�&��� �H������������������:���I1 – DbGrid1Exibir informações da tabela EMPREGADOS4, através da SQLClientDataSet1.Evento: Não existe.

2 – EdtMatricArmazenar em memória o número da matrícula do funcionário a ser inserida oualterada até que possa ser transferido para o banco de dados.Evento: Não existe.

3 – EdtNomeArmazenar em memória o nome do funcionário a ser inserido ou alterado.Evento: Não existe.

Page 175: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 177

4 – EdtEnderArmazenar em memória o endereço do funcionário a ser inserido ou alterado.Evento: Não existe.

5 – EdtSalarioArmazenar em memória o salário do funcionário a ser inserido ou alterado.Evento: Não existe.

6 – Button1A rotina de inclusão deve colocar a tabsheet1 em condições de inserir informaçõesem seus componentes, para transferi-las posteriormente para o banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button1Click(Sender: TObject); begin iniciatransacao; panel2.enabled:= true; pinclui:= true; edtmatric.setfocus; end;

Objetivo: Iniciar uma transação, caso nenhuma esteja ativa, alterar o valor da vari-ável global pinclui, informando que na tabela EMPREGADOS4 um novo registroserá inserido e alterar o valor da propriedade enabled para true no panel2.

NO TA: Em todos os botões contidos nas tabsheets de nosso projeto, a procedureiniciatransação está presente, executando a mesma função. Dessa forma, não serámais explicada a função da mesma.

6 – Button2A rotina de exclusão permite que um funcionário e seus respectivos relacionamen-tos sejam apagados, através da constraint criada.

Evento: OnClickCódigo: procedure TForm1.Button2Click(Sender: TObject); var stringsql: string; begin try iniciatransacao; stringsql:= 'delete from empregados4 '+ 'where matricula = '+#39+ datamodule2.SQLClientDataSet1.FieldValues['MATRICULA']+#39; executasql(stringsql);

Page 176: Delphi 6 com Oracle

178 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

except showmessage('Não foi possível excluir o registro !'); end; executarefresh; end;

Objetivo: Exclui o registro nas tabelas EMPREGADOS4, EMPXCARGO4 e EM-PXDEP4 utilizando o registro corrente do SQLClientDataSet1, onde logo em se-guida um refresh é executado para que a exclusão reflita no dbgrid.

6 – Button3A alteração deve ser capaz de modificar as informações contidas nos componentespertencentes a tabsheet1.

Evento: OnClickCódigo: procedure TForm1.Button3Click(Sender: TObject); begin iniciatransacao; panel2.enabled:= true; pinclui:= false; with datamodule2.SQLClientDataSet1 do begin edtmatric.text:= FieldValues['MATRICULA']; edtnome.text:= FieldValues['NOME']; edtsalario.text:= FieldValues['SALARIO']; edtender.text:= FieldValues['ENDERECO']; end; edtmatric.enabled:= false; edtnome.setfocus; end;

Objetivo: Transfere os valores dos campos da tabela EMPREGADOS4, contidos noregistro corrente do SQLClientDataSet1, para a propriedade text dos componentes databsheet1. Alterar o valor da variável global pinclui, informando que o registro seráalterado, modificar o valor da propriedade enabled para true no panel2, permitindo queas informações sejam modificadas e mudar o valor da propriedade enabled para falseno componente edtmatric, pois o valor da chave primária não pode ser alterado.

6 – Button4O botão Ok é responsável por transferir as informações contidas nos componentesda tabsheet1 para o banco de dados Oracle, alterando ou inserindo um registro.

Evento: OnClickCódigo: procedure TForm1.Button4Click(Sender: TObject); var stringsql: string;

Page 177: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 179

begin if pinclui then begin try stringsql:= 'insert into empregados4 values ('+#39; stringsql:= stringsql + edtmatric.text+#39+', '+#39; stringsql:= stringsql + edtnome.text+#39+', '; stringsql:= stringsql + edtsalario.text+', '+#39; stringsql:= stringsql + edtender.text+#39+')'; executasql(stringsql); except showmessage('Não foi possível incluir o registro !'); end; end else begin try stringsql:= 'update empregados4 set '; stringsql:= stringsql + 'matricula = '+#39+edtmatric.text+#39+', '; stringsql:= stringsql + 'nome = '+#39+edtnome.text+#39+', '; stringsql:= stringsql + 'salario = '+edtsalario.text+', '; stringsql:= stringsql + 'endereco = '+#39+edtender.text+#39+' '; stringsql:= stringsql + 'where matricula = '+#39+edtmatric.text+#39; executasql(stringsql); except showmessage('Não foi possível alterar o registro !'); end; end;

edtmatric.enabled:= true; panel2.enabled:= false; executarefresh; limpacomponentes; end;

Objetivo: Em função do valor da variável global pinclui, um comando SQL deinclusão ou alteração deve ser executado, transferindo o conteúdo da propriedadetext de cada componente para a tabela EMPREGADOS4 1. É preciso modificar ovalor da propriedade enabled para false no panel2, executando logo em seguida umrefresh para que a atualização reflita no dbgrid.

6 – Button5Essa rotina altera para permanente as atualizações pendentes em todas as tabelas dobanco de dados.

Evento: OnClickCódigo: procedure TForm1.Button5Click(Sender: TObject); begin try

1 É importante lembrar que as atualizações efetuadas estão pendentes, como já foi explicado.

Page 178: Delphi 6 com Oracle

180 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

datamodule2.sqlconnection1.commit(td); executarefresh; except showmessage('Não foi possível confirmar a transação !'); end; end;

Objetivo: Executar o comando COMMIT no banco de dados, finalizando a transa-ção, e um refresh para que a atualização reflita no dbgrid.

6 – Button6Cancelar as atualizações pendentes em todas as tabelas do banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button6Click(Sender: TObject); begin try datamodule2.sqlconnection1.rollback(td); executarefresh; except showmessage('Não foi possível desfazer a transação !'); end; end;

Objetivo: Executar o comando ROLLBACK, finalizando a transação no banco dedados e um refresh para que a atualização reflita no dbgrid.

���!��%�"�,�;�&�����H����������������I

1 – DbGrid2Exibir informações da tabela CARGOS4, através do SQLClientDataSet1.Evento: Não existe.

2 – EdtCodCargoArmazenar em memória, até ser transferido para o banco de dados, o código docargo a ser inserido ou alterado.Evento: Não existe.

3 – EdtDescCargoArmazenar em memória, até ser transferido para o banco de dados, a descrição docargo a ser inserido ou alterado.Evento: Não existe.

Page 179: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 181

4 – Button8A rotina de inclusão deve ser capaz de colocar a tabsheet2 em condições de inseririnformações nos componentes edtcodcargo e edtdesccargo, de onde será transferi-da posteriormente para o banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button8Click(Sender: TObject); begin iniciatransacao; panel4.enabled:= true; pinclui:= true; edtcodcargo.setfocus; end;

Objetivo: Alterar o valor da variável global pinclui, informando ao projeto que umnovo registro será inserido na tabela CARGOS4 e alterar o valor da propriedadeenabled para true no panel4, permitindo que informações sejam inseridas nos com-ponentes.

4 – Button9A rotina de exclusão deve permitir que um cargo e seus respectivos relacionamen-tos, através da constraint criada, sejam apagados.

Evento: OnClickCódigo:

procedure TForm1.Button9Click(Sender: TObject); var stringsql: string; begin try iniciatransacao; stringsql:= 'delete from cargos4 '+ 'where codcargo = '+#39+ datamodule2.SQLClientDataSet1.FieldValues['CODCARGO']+#39; executasql(stringsql); except showmessage('Não foi possível excluir o registro !'); end; executarefresh; end;

Objetivo: Excluir os registros nas tabelas CARGOS4 e EMPXCARGO4, utilizandoo registro corrente da SQLQuery1, executando logo em seguida um refresh paraque a exclusão reflita no dbgrid.

Page 180: Delphi 6 com Oracle

182 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

4 – Button10A rotina de alteração deve ser capaz de colocar a tabsheet2 em condições de alteraras informações contidas nos componentes edtcodcargo e edtdesccargo.

Evento: OnClickCódigo:

procedure TForm1.Button10Click(Sender: TObject); begin iniciatransacao; panel4.enabled:= true; pinclui:= false; with datamodule2.SQLClientDataSet1 do begin edtcodcargo.text:= FieldValues['CODCARGO']; edtdesccargo.text:= FieldValues['DESCRICAO']; end; edtcodcargo.enabled:= false; edtdesccargo.setfocus; end;

Objetivo: Transferir para a propriedade text dos componentes edtcodcargo eedtdesccargo, os valores dos campos CODCARGO e DESCRICAO, contidos noregistro corrente do SQLClientDataSet1. Alterar o valor da variável global pinclui,informando ao projeto que o registro será alterado na tabela CARGOS, alterar o valorda propriedade enabled para true no panel4, permitindo que as informações sejammodificadas nos componentes e, por fim, alterar o valor da propriedade enabled parafalse no componente edtcodcargo, pois não devemos alterar o valor da chave primá-ria.

4 – Button11A rotina contida no botão Ok é responsável por transferir as informações contidasnos componentes da tabsheet2 para o banco de dados Oracle, alterando ou inserin-do um registro.

Evento: OnClickCódigo: procedure TForm1.Button11Click(Sender: TObject); var stringsql: string; begin if pinclui then begin try stringsql:= 'insert into cargos4 values ('+#39; stringsql:= stringsql + edtcodcargo.text+#39+', '+#39; stringsql:= stringsql + edtdesccargo.text+#39+')'; executasql(stringsql); except showmessage('Não foi possível incluir o registro !'); end;

Page 181: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 183

end else begin try stringsql:= 'update cargos4 set '; stringsql:=stringsql+'codcargo='+#39+edtcodcargo.text+#39+', '; stringsql:=stringsql+'descricao='+#39+edtdesccargo.text+#39+' '; stringsql:=stringsql+'where codcargo='+#39+edtcodcargo.text+#39; executasql(stringsql); except showmessage('Não foi possível alterar o registro !'); end; end;

edtcodcargo.enabled:= true; panel2.enabled:= false; executarefresh; limpacomponentes; end;

Objetivo: Verificar, através da variável global pinclui, se um comando SQL deinclusão ou alteração deve ser executado, transferindo a informação contida napropriedade text de cada componente para a tabela CARGOS4 2. Alterar o valor dapropriedade enabled para false no panel4 e executar um refresh para que a atuali-zação reflita no dbgrid.

4 – Button12Fica a cargo dessa rotina tornar permanentes as atualizações pendentes em todas astabelas do banco de dados.

Evento: OnClickCódigo: Deve apontar para o evento Onclick do Button5.

Objetivo: Executar o comando COMMIT, finalizando a transação no banco de da-dos, e executar um refresh para que a atualização reflita no dbgrid.

4 – Button13Esta rotina, ao contrário da anterior, cancela as atualizações pendentes em todas astabelas do banco de dados.

Evento: OnClickCódigo: Deve apontar para o evento Onclick do Button6.

2 É importante lembrar que as atualizações efetuadas estão pendentes, como já foi explicado.

Page 182: Delphi 6 com Oracle

184 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Objetivo: Executar o comando ROLLBACK, finalizando a transação no banco dedados, e executar um refresh para que a atualização reflita no dbgrid.

���!��(�"�,�;�&���$�H�����������#�!��� �����I

1 – DbGrid3Exibir informações da tabela DEPTO4, através do SQLClienteDataSet1.Evento: Não existe.

2 – EdtCodDepArmazenar em memória o código do departamento a ser inserido ou alterado atéque possa ser transferido para o banco de dados.Evento: Não existe.

3 – EdtDescDepArmazenar em memória a descrição do departamento a ser inserido ou alterado atéque possa ser transferido para o banco de dados.Evento: Não existe.

4 – Button15Esta rotina deve colocar a tabsheet3 em condições de inserir informações nos com-ponentes, para posterior transferência para o banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button15Click(Sender: TObject); begin iniciatransacao; panel6.enabled:= true; pinclui:= true; edtcoddepto.setfocus; end;

Objetivo: Alterar o valor da variável global pinclui, informando que um novo re-gistro será inserido na tabela DEPTO4 e alterar o valor da propriedade enabledpara true no panel6.

4 – Button16Esta rotina permite que um departamento e seu respectivo relacionamento sejamapagados, através da constraint criada.

Evento: OnClickCódigo: procedure TForm1.Button16Click(Sender: TObject);

Page 183: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 185

var stringsql: string; begin try iniciatransacao; stringsql:= 'delete from depto4 '+ 'where coddep = '+#39+ datamodule2.SQLClientDataSet1.FieldValues['CODDEP']+#39; executasql(stringsql); except showmessage('Não foi possível excluir o registro !'); end; executarefresh; end;

Objetivo: Excluir os registros nas tabelas DEPTO4 e EMPXDEP4, utilizando oregistro corrente do SQLCLientDataSet1 e executar em seguida um refresh paraque a exclusão reflita no dbgrid.

4 – Button17A rotina de alteração de um departamento deve ser capaz de colocar a tabsheet3 emcondições de alterar as informações contidas em seus componentes.

Evento: OnClickCódigo:

procedure TForm1.Button17Click(Sender: TObject); begin iniciatransacao; panel6.enabled:= true; pinclui:= false; with datamodule2.SQLClientDataSet1 do begin edtcoddepto.text:= FieldValues['CODDEP']; edtdescdepto.text:= FieldValues['DESCRICAO']; end; edtcoddepto.enabled:= false; edtdescdepto.setfocus; end;

Objetivo: Os valores dos campos CODDEP e DESCRICAO, contidos no registrocorrente do SQLClientDataSet1, devem ser transferidos para a propriedade text doscomponentes edtcoddepto e edtdescdepto. O valor da variável global pinclui seráalterado, informando que o registro será alterado na tabela DEPTO4. Alterar ovalor da propriedade enabled para true no panel6, permitindo que as informaçõessejam modificadas nos componentes e, como não devemos alterar o valor da chaveprimária, a propriedade enabled será modificada para false no componente edtco-ddepto.

4 – Button18

Page 184: Delphi 6 com Oracle

186 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

A rotina contida no botão Ok é responsável por transferir as informações contidasnos componentes da tabsheet3 para o banco de dados Oracle, alterando ou inserin-do um registro.

Evento: OnClickCódigo:

procedure TForm1.Button18Click(Sender: TObject); var stringsql: string; begin if pinclui then begin try stringsql:= 'insert into depto4 values ('+#39; stringsql:= stringsql + edtcoddepto.text+#39+', '+#39; stringsql:= stringsql + edtdescdepto.text+#39+')'; executasql(stringsql); except showmessage('Não foi possível incluir o registro !'); end; end else begin try stringsql:= 'update depto4 set '; stringsql:= stringsql + 'coddep = '+#39+edtcoddepto.text+#39+', '; stringsql:= stringsql +'descricao = '+#39+edtdescdepto.text+#39+' '; stringsql:= stringsql +'where coddep = '+#39+edtcoddepto.text+#39; executasql(stringsql); except showmessage('Não foi possível alterar o registro !'); end; end;

edtcoddepto.enabled:= true; panel4.enabled:= false; executarefresh; limpacomponentes; end;

Objetivo: Em função do valor da variável global pinclui, um comando SQL deinclusão ou alteração deve ser executado, onde a informação contida na proprieda-de text de cada componente será transferida para a tabela DEPTO43. Modificar ovalor da propriedade enabled para false no panel6, executando logo em seguida umrefresh para que a atualização reflita no dbgrid.

4 – Button19Essa rotina transforma em permanente as atualizações pendentes em todas as tabe-las do banco de dados.

3 É importante lembrar que as atualizações efetuadas estão pendentes, como já foi explicado.

Page 185: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 187

Evento: OnClickCódigo: Deve apontar para o evento Onclick do Button5.

Objetivo: Executar o comando COMMIT no banco de dados, finalizando a transa-ção, e um refresh para que a atualização reflita no dbgrid.

4 – Button20Ao contrário da anterior, cancela as atualizações pendentes em todas as tabelas dobanco de dados.

Evento: OnClickCódigo:

Deve apontar para o evento Onclick do Button6.

Objetivo: Executar o comando ROLLBACK no banco de dados, finalizando a tran-sação, e um refresh para que a atualização reflita no dbgrid.

���!��+�"�,�;�&���%�H������������������� ����������� !��������������I

1 – DbGrid4Exibir informações da tabela EMPXCARGO4, através do SQLClientDataSet.Evento: Não existe.

2 – EdtMatric2Armazenar em memória a matrícula do funcionário a ser inserida ou alterada atéque possa ser transferida para o banco de dados.Evento: Não existe.

3 –EdtCodCargo2Armazenar em memória o código do cargo a ser inserido ou alterado até que possaser transferido para o banco de dados.Evento: Não existe.

4 – Button22Essa rotina deve colocar a tabsheet4 em condições de inserir informações noscomponentes, para posterior transferência para o banco de dados.

Evento: OnClickCódigo:

procedure TForm1.Button22Click(Sender: TObject);

Page 186: Delphi 6 com Oracle

188 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

begin iniciatransacao; panel8.enabled:= true; pinclui:= true; edtmatric2.setfocus; end;

Objetivo: Alterar o valor da variável global pinclui, informando que um novo re-gistro será inserido na tabela EMPXCARGO4 e alterar o valor da propriedade ena-bled para true no panel8.

4 – Button23Essa rotina permite que um funcionário e seu respectivo cargo sejam apagados.

Evento: OnClickCódigo: procedure TForm1.Button23Click(Sender: TObject); var stringsql: string; begin try iniciatransacao; stringsql:= 'delete from empxcargo4 '+ 'where matricula = '+#39+ datamodule2.SQLClientDataSet1.FieldValues['MATRICULA']+#39+' and '+ 'codcargo = '+#39+ datamodule2.SQLClientDataSet1.FieldValues['CODCARGO']+#39; executasql(stringsql); except showmessage('Não foi possível excluir o registro !'); end; executarefresh; end;

Objetivo: Excluir o registro do relacionamento entre empregado e cargo, na tabelaEMPXCARGO4, utilizando o registro corrente do SQLCLientDataSet1 e executarem seguida um refresh para que a exclusão reflita no dbgrid.

4 – Button24A rotina de alteração de um empregado e seu cargo deve ser capaz de colocar atabsheet4 em condições de alterar as informações contidas em seus componentes.

Evento: OnClickCódigo: procedure TForm1.Button24Click(Sender: TObject); begin iniciatransacao; panel8.enabled:= true; pinclui:= false; with datamodule2.SQLClientDataSet1 do begin edtmatric2.text:= FieldValues['MATRICULA'];

Page 187: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 189

edtcodcargo2.text:= FieldValues['CODCARGO']; end; edtmatric2.enabled:= false; edtcodcargo2.setfocus; end;

Objetivo: Os valores dos campos MATRICULA E CODCARGO, contidos no re-gistro corrente do SQLClientDataSet1, devem ser transferidos para a propriedadetext dos componentes edtmatric2 e edtcodcargo2. O valor da variável global pin-clui será alterado, informando que o registro também será alterado na tabelaEMPXCARGO4. Alterar o valor da propriedade enabled para true no panel8, per-mitindo que as informações sejam modificadas nos componentes e, como não de-vemos alterar o valor da chave primária, a propriedade enabled será modificadapara false no componente edtmatric2.

4 – Button25A rotina contida no botão Ok é responsável por transferir as informações contidasnos componentes da tabsheet4 para o banco de dados Oracle, alterando ou inserin-do um registro.

Evento: OnClickCódigo: procedure TForm1.Button25Click(Sender: TObject); var stringsql: string; begin if pinclui then begin try stringsql:= 'insert into empxcargo4 values ('+#39; stringsql:= stringsql + edtmatric2.text+#39+', '+#39; stringsql:= stringsql + edtcodcargo2.text+#39+')'; executasql(stringsql); except showmessage('Não foi possível incluir o registro !'); end; end else begin try stringsql:= 'update empxcargo4 set '; stringsql:=stringsql+'matricula = '+#39+edtmatric2.text+#39+', '; stringsql:=stringsql+'codcargo = '+#39+edtcodcargo2.text+#39+' '; stringsql:= stringsql+'where matricula ='+#39+ edtmatric2.text+#39+' and '; stringsql:= stringsql + ' codcargo = '+#39+ datamodule2.SQLClientDataSet1.FieldValues['CODCARGO']+#39; executasql(stringsql); except showmessage('Não foi possível alterar o registro !'); end; end;

Page 188: Delphi 6 com Oracle

190 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

edtmatric2.enabled:= true; panel8.enabled:= false; executarefresh; limpacomponentes; end;

Objetivo: Em função do valor da variável global pinclui, um comando SQL deinclusão ou alteração deve ser executado. As informações contidas na propriedadetext de cada componente serão transferidas para a tabela EMPXCARGO44. O valorda propriedade enabled será alterado para false no panel6, executando logo emseguida um refresh para que a atualização reflita no dbgrid.

4 – Button26Essa rotina transforma em permanente as atualizações pendentes em todas as tabe-las do banco de dados.

Evento: OnClickCódigo:

Deve apontar para o evento Onclick do Button5.

Objetivo: Finaliza a transação, executando o comando COMMIT no banco de da-dos, e um refresh para que a atualização reflita no dbgrid.

4 – Button27Ao contrário da anterior, cancela as atualizações pendentes em todas as tabelas dobanco de dados.

Evento: OnClickCódigo:

Deve apontar para o evento Onclick do Button6.

Objetivo: Executar o comando ROLLBACK no banco de dados, finalizando a tran-sação, e um refresh para que a atualização reflita no dbgrid.

���!��-�"�,�;�&���(�H������������������� ����������� !���������#�!��� �����I

1 – DbGrid5Exibir informações da tabela EMPXDEP4, através do SQLClientDataSet.

4 É importante lembrar que as atualizações efetuadas estão pendentes, como já foi explicado.

Page 189: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 191

Evento: Não existe.

2 – EdtMatric3Armazenar em memória a matrícula do funcionário a ser inserida ou alterada atéque possa ser transferida para o banco de dados.Evento: Não existe.

3 –EdtCodDepto2Armazenar em memória o código do departamento a ser inserido ou alterado atéque possa ser transferido para o banco de dados.Evento: Não existe.

4 – Button29Essa rotina deve colocar a tabsheet5 em condições de inserir informações noscomponentes, para posterior transferência para o banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button29Click(Sender: TObject); begin iniciatransacao; panel10.enabled:= true; pinclui:= true; edtmatric3.setfocus; end;

Objetivo: Informar que um novo registro será inserido na tabela EMPXDEP4, mo-dificar o valor da variável global pinclui, e alterar o valor da propriedade enabledpara true no panel10.

4 – Button30Esta rotina permite que um funcionário e seu respectivo departamento sejam apagados.

Evento: OnClickCódigo: procedure TForm1.Button30Click(Sender: TObject); var stringsql: string; begin try iniciatransacao; stringsql:= 'delete from empxdep4 '+ 'where matricula = '+#39+ datamodule2.SQLClientDataSet1.FieldValues['MATRICULA']+#39+' and '+ 'coddep = '+#39+ datamodule2.SQLClientDataSet1.FieldValues['CODDEP']+#39; executasql(stringsql); except

Page 190: Delphi 6 com Oracle

192 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

showmessage('Não foi possível excluir o registro !'); end; executarefresh; end;

Objetivo: Na tabela EMPXCARGO4, excluir o relacionamento entre empregado edepartamento, utilizando o registro corrente do SQLCLientDataSet1 e executar emseguida um refresh para que a exclusão reflita no dbgrid.

4 – Button31Colocar a tabsheet4 em condições de modificar as informações contidas em seuscomponentes, através da rotina de alteração de um empregado e seu departamento.

Evento: OnClickCódigo: procedure TForm1.Button31Click(Sender: TObject); begin iniciatransacao; panel10.enabled:= true; pinclui:= false; with datamodule2.SQLClientDataSet1 do begin edtmatric3.text:= FieldValues['MATRICULA']; edtcoddepto2.text:= FieldValues['CODDEP']; end; edtmatric3.enabled:= false; edtcoddepto2.setfocus; end;

Objetivo: Através do registro corrente do SQLClientDataSet1, os valores dos cam-pos MATRICULA E CODDEP devem ser transferidos para a propriedade text doscomponentes edtmatric3 e edtcoddepto2. Informar que o registro será alterado natabela EMPXDEP4, através da alteração do valor da variável global pinclui. Modi-ficar o valor da propriedade enabled para true no panel10, permitindo que as in-formações sejam modificadas nos componentes e, como não devemos alterar ovalor da chave primária, a propriedade enabled será modificada para false no com-ponente edtmatric3.

4 – Button32Transferir as informações contidas nos componentes da tabsheet5 para o banco dedados Oracle, alterando ou inserindo um registro, através da rotina contida no bo-tão Ok.

Evento: OnClickCódigo: procedure TForm1.Button32Click(Sender: TObject); var stringsql: string; begin

Page 191: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 193

if pinclui then begin try stringsql:= 'insert into empxdep4 values ('+#39; stringsql:= stringsql + edtmatric3.text+#39+', '+#39; stringsql:= stringsql + edtcoddepto2.text+#39+')'; executasql(stringsql); except showmessage('Não foi possível incluir o registro !'); end; end else begin try stringsql:= 'update empxdep4 set '; stringsql:=stringsql+'matricula = '+#39+edtmatric3.text+#39+', '; stringsql:=stringsql + 'coddep = '+#39+edtcoddepto2.text+#39+' '; stringsql:= stringsql + 'where matricula ='+#39+ edtmatric3.text+#39+' and '; stringsql:= stringsql + ' coddep = '+#39+ datamodule2.SQLClientDataSet1.FieldValues['CODDEP']+#39; executasql(stringsql); except showmessage('Não foi possível alterar o registro !'); end; end;

edtmatric2.enabled:= true; panel10.enabled:= false; executarefresh; limpacomponentes; end;

Objetivo: Executar um comando SQL de inclusão ou exclusão, em função do valorda variável global pinclui. As informações contidas na propriedade text de cadacomponente serão transferidas para a tabela EMPXDEP45. O valor da propriedadeenabled será alterado para false no panel10, executando logo em seguida um re-fresh para que a atualização reflita no dbgrid.

4 – Button33Esta rotina transforma em permanente as atualizações pendentes em todas as tabe-las do banco de dados.

Evento: OnClickCódigo: Deve apontar para o evento Onclick do Button5.

Objetivo: Finaliza a transação, executando o comando COMMIT no banco de da-dos, e um refresh para que a atualização reflita no dbgrid.

5 É importante lembrar que as atualizações efetuadas estão pendentes, como já foi explicado.

Page 192: Delphi 6 com Oracle

194 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

4 – Button34Ao contrário da anterior, cancela as atualizações pendentes em todas as tabelas dobanco de dados.

Evento: OnClickCódigo:

Deve apontar para o evento Onclick do Button6.

Objetivo: Executar o comando ROLLBACK no banco de dados, finalizando a tran-sação, e um refresh para que a atualização reflita no dbgrid.

���!����"�,�;�&���%�H��������������������:�������������I

20 – Button36Gerar a consulta para um funcionário, em função dos valores informados nos com-ponentes contidos na tabsheet6.

Evento: OnClickCódigo:

procedure TForm1.Button36Click(Sender: TObject); var pselect, pfrom, pwhere, pgroup, stringsql: string; lescolheu_sal: boolean; ind: integer; begin ind:= 0; lescolheu_sal:= false;

pselect:= 'SELECT Empregados4.MATRICULA, Empregados4.Nome, '+ ' Empregados4.SALARIO,'+ ' Cargos4.DESCRICAO, '+ ' Depto4.DESCRICAO ';

pfrom:= ' FROM EMPREGADOS4 Empregados4, EMPXCARGO4 Empxcargo4,'+ ' EMPXDEP4 Empxdep4,'+ ' CARGOS4 Cargos4, DEPTO4 Depto4 ';

pwhere:= ' WHERE (Empregados4.MATRICULA = Empxcargo4.MATRICULA) '+ ' AND (Cargos4.CODCARGO = Empxcargo4.CODCARGO) '+ ' AND (Empregados4.MATRICULA = Empxdep4.MATRICULA) '+ ' AND (Depto4.CODDEP = Empxdep4.CODDEP) '; pgroup:= '';

if rbmaisal.checked then begin pselect:= 'SELECT MAX(Empregados4.SALARIO)'; lescolheu_sal:= true; end;

Page 193: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via dbExpress • 195

if rbmensal.checked then begin pselect:= 'SELECT MIN(Empregados4.SALARIO)'; lescolheu_sal:= true; end;

if rbmedsal.checked then begin pselect:= 'SELECT AVG(Empregados4.SALARIO)'; lescolheu_sal:= true; end;

if lescolheu_sal then begin pselect:= pselect + ',Depto4.DESCRICAO '; pgroup:= 'GROUP BY Depto4.DESCRICAO'; end;

with datamodule2.sqlclientdataset1 do begin close; if rbsldepto.checked then begin pwhere:= pwhere+' AND (Depto4.CODDEP = '+#39+ edtcoddepto3.text+#39+')'; end;

if rbslcargo.checked then begin pwhere:= pwhere+' AND (Cargos4.CODCARGO ='+#39+ edtcodcargo3.text+#39+')'; end;

if not lescolheu_sal then begin if rbslfunci.checked then begin pwhere:= pwhere+' AND (Empregados4.MATRICULA = '+#39+ edtmatric4.text+#39+')'; end; end;

stringsql:= pselect+pfrom+pwhere+pgroup; commandtext:= stringsql; open; end; end;

Objetivo: Criar uma consulta, utilizando as tabelas FUNCIONARIOS4, DEPTO4,CARGOS4, EMPXDEP4, EMPXCARGO4, através de 4 variáveis, que irão com-por o comando SELECT. Sendo elas:

• pselect – Escolhe os campos que serão exibidos pela consulta;• pfrom – Seleciona as tabelas da consulta;• pwhere – Seleciona a condição da consulta;• pgroup – Agrupa os dados, se necessário, da consulta.

Cada variável recebe um valor inicial, podendo ser inteiramente modificado ouconcatenado com outro, variando conforme a escolha de alguma opção da tela deconsulta. Ao final, seus valores serão somados em uma única variável: stringsql.

Page 194: Delphi 6 com Oracle

196 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Exemplo1

Selecionar todos os funcionários que trabalham no departamento cujo código éidentificado pelo valor ‘03’.

O valor das variáveis pselect, pfrom e pgroup não será alterado. Somente o valor depwhere será modificado, sendo adicionado ao final da variável o código que irá in-cluir a condição para que só os funcionários do departamento ‘03’ sejam exibidos.

Exemplo2

Selecionar a média salarial de todos os funcionários que trabalham em cada depar-tamento da empresa.

O valor da variável pselect será modificado, exibindo somente a coluna que iráconter a média salarial, através de uma função de grupo (AVG), e pgroup, neces-sária para agruparmos a média por departamento. As demais variáveis permanecemcom seus valores iniciais.

O bservação: A consulta é gerada através de um join realizado nas cinco tabelascriadas, onde obteremos de cada uma a informação necessária. A figura 10.50 nosmostra o relacionamento de cada tabela:

Obtém o nome do departamento em Obtém o nome do cargo deque cada funcionário trabalha. cada funcionário da empresa.

������ G �(G

Page 195: Delphi 6 com Oracle

197

11. Conexão com o Banco de DadosOracle via ADO

�� !��������6���������������C��O Delphi, até sua versão 4, só acessava o banco de dados Oracle através da BDE.A Inprise viu a necessidade de estender o acesso ao banco, em função do cresci-mento da programação voltada para internet, disseminação do desenvolvimento emmúltiplas camadas e o fato de nem todos os provedores terem o BDE instalado.

A camada ADO (ActiveX Data Objects) é um padrão Microsoft para acesso a ban-co de dados, através da OLE DB, que, além de possuir drivers nativos para o co-nexão aos bancos, é altamente integrado à internet.

A figura 11.1 nos mostra, utilizando os principais componentes, como o Delphitrata o acesso ao banco de dados via ADO.

,8#/����������O componente TADOConnection é responsável por estabelecer uma conexão como banco de dados Oracle, através da camada ADO. A seguir estão listadas as prin-cipais propriedades deste componente.

Nome: ConnectedTipo: BooleanDescrição: Indica se foi estabelecida uma conexão com o banco de dados Oracle.

Page 196: Delphi 6 com Oracle

198 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

TADOConnection TDataSource

TADODataSet

TADOCommand TADOQuery

������ �

Nome: ConnectionStringTipo: WideStringDescrição: Responsável por definir a string de conexão entre a camada ADO e obanco de dados que será utilizado, no nosso caso, o Oracle.

Nome: ConnectionTimeOutTipo: IntegerDescrição: Determina um tempo limite para ser feita a conexão com o banco dedados Oracle.

Nome: CursorLocationTipo: TCursorLocationDescrição: Define onde estará o cursor para as tabelas.

Nome: LoginPromptTipo: BooleanDescrição: Especifica se a caixa de login será exibida quando o aplicativo tentarum conexão no banco de dados Oracle.

Nome: ModeTipo: TConnectModeDescrição: Define o modo de conexão, se será somente leitura ou leitura e gravação.

Page 197: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 199

,8#/2���O componente TADOQuery é similar ao componente TQuery da aba BDE, sendoindicado para conexões cliente/servidor. A seguir estão listadas as principais propri-edades deste componente.

Nome: ConnectionTipo: TADOConnectionDescrição: Especifica o componente TADOConnection a ser utilizado, permitindoassim a conexão com o banco de dados Oracle.

Nome: CursorLocationTipo: TCursorLocationDescrição: Informa se o componente irá trabalhar em CachedUpdates.� clUseClient: dados serão armazenados no cliente e comandos SQL (insert,

update e delete);� clUseServer: as alterações serão enviadas automaticamente para o servidor.

Nome: CursorTypeTipo: TCursorTypeDescrição: Define qual t ipo de cursor será utilizado:– ctUnspecified: T ipo de cursor não predefinido pelo componente;– ctOpenForwardOnly: Cursor unidirecional, não “bufferiza” os registros na me-

mória;– ctKeySet: Cursor bidirecional, não concorrente. Os registros são “bufferizados”

no result set. Alterações feitas por transações concorrentes não estarão disponí-veis;

– ctDynamic: Bidirecional e concorrente. Utiliza mais recursos do sistema e apre-senta a pior performance quando comparado com os outros;

– ctStatic: Cópia dos registros, onde qualquer tipo de transação concorrente nãoserá visualizada.

Nome: MarshalOptionsTipo: TMarshalOptionDescrição: Define quais registros serão devolvidos para o servidor:– moMarshalAll – todos os registros serão enviados;– moMarshalModifiedOn ly – somente os registros mo dificado s serão envia-

dos.

Page 198: Delphi 6 com Oracle

200 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Nome: SQ LTipo: StringDescrição: Armazena uma declaração SQL.

A seguir estão listados os principais métodos do componente TADOQuery.

Nome: CloseDescrição: Altera o valor da propriedade Active para false.

Nome: ExecSqlDescrição: Executa uma declaração SQL que não retorna um conjunto de resulta-dos (insert, update e delete).

Nome: O penDescrição: Altera o valor da propriedade Active para true, executando uma decla-ração SQL que retorne um conjunto de resultados.

,8#/#������Esse componente é a classe-pai da qual descendem os objetos TADOTabel,TADOQuery e TADOStoredProc. Portanto, tem os mesmos atributos que seusdescendentes. Abaixo estão listadas as principais propriedades deste componente.

Nome: CommandTextTipo: StringDescrição: Conterá o comando SQL a ser executado, dependendo do valor da pro-priedade CommandType.

Nome: CommandTypeTipo: TSQLCommandTypeDescrição: indicará o tipo de comando que estará contido na propriedadeCommandText.

Nome: ConnectionTipo: TADOConnectionDescrição: Especifica o componente TADOConnection a ser utilizado, permitindoassim a conexão com o banco de dados Oracle.

Nome: CursorLocationTipo: TCursorLocationDescrição: Informa se o componente irá trabalhar em CachedUpdates.

Page 199: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 201

– clUseClient: dados serão armazenados no cliente e comandos SQL(insert, update e delete);

– clUseServer: as alterações serão enviadas automaticamente para o servidor.

Nome: CursorTypeTipo: TCursorTypeDescrição: Define qual t ipo de cursor será utilizado:– ctUnspecified: T ipo de cursor não predefinido pelo componente;– ctOpenForwardOnly: Cursor unidirecional, não “bufferiza” os registros na me-

mória;– ctKeySet: Cursor bidirecional, não concorrente. Os registros são “bufferizados”

no result set. Alterações feitas por transações concorrentes não estarão disponí-veis;

– ctDynamic: Bidirecional e concorrente. Utiliza mais recursos do sistema e apre-senta a pior performance quando comparado com os outros;

– ctStatic: Cópia dos registros, onde qualquer tipo de transação concorrente nãoserá visualizada.

Nome: MarshalOptionsTipo: TMarshalOptionDescrição: Define quais registros serão devolvidos para o servidor:– moMarshalAll – todos os registros serão enviados;– moMarshalModifiedOnly – somente os registros modificados serão enviados.

A seguir estão listados os principais métodos do componente TADODataSet.

Nome: CloseDescrição: Altera o valor da propriedade Active para false.

Nome: O penDescrição: Altera o valor da propriedade Active para true, executando uma decla-ração SQL que retorne um conjunto de resultados.

,8#/�� ���Este componente serve para enviar comandos SQL para o servidor, não permitindoa ligação com objetos DataControl. Operações de update, delete e insert são maisrápidas quando executadas através desse componente, pois possui uma performan-ce otimizada para instruções que não retornem um conjunto de dados. A seguirestão listadas as principais propriedades deste componente:

Page 200: Delphi 6 com Oracle

202 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Nome: CommandTextTipo: StringDescrição: Conterá o comando SQL a ser executado.

Nome: CommandTypeTipo: TSQLCommandTypeDescrição: Indicará o tipo de comando que estará contido na propriedadeCommandText.

Nome: ConnectionTipo: TADOConnectionDescrição: Especifica o componente TADOConnection a ser utilizado, permitindoassim a conexão com o banco de dados Oracle.

A seguir, o principal método do componente TADOCommand:

Nome: ExecuteDescrição: Executa o comando SQL.

,#��������Permite estabelecer uma conexão entre um ou mais componentes Data Controls(dbgrids, dbedit, etc.) e cada componente TADOQuery, TADODataSet, TADOTable.Abaixo é mostrada a propriedade mais importante deste componente.

Nome: DataSetTipo:TDataSetDescrição: Especifica o dataset do qual o componente obtém seus dados.

�C� !���#��!&�F8#/ ��� �/����As tabelas que serão criadas são bem simples, já que o objetivo maior desse exem-plo é mostrar a conexão com o banco de dados Oracle através da aba ADO.

Conforme exemplos anteriores, será utilizada a constraint FOREIGN KEY com acláusula DELETE CASCADE. Dessa forma, toda a integridade de dados será con-trolada pelo banco de dados Oracle.

Page 201: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 203

� Criando a tabela de pais:

SQL > CREATE TABLE PAIS

2 (MATRICULA_P VARCHAR2(3) NOT NULL, 3 NOME VARCHAR2(50) NOT NULL,

4 CONSTRAINT PK_PAI PRIMARY KEY (MATRICULA_P));

� Criando a tabela de filhos:

SQL > CREATE TABLE FILHO 2 (MATRICULA_P VARCHAR2(3) NOT NULL,

3 MATRICULA_F VARCHAR2(3) NOT NULL, 4 NOME VARCHAR2(50) NOT NULL,

5 CONSTRAINT PK_FILHO PRIMARY KEY (MATRICULA_P,MATRICULA_F),

6 CONSTRAINT PK_FILHO2 FOREIGN KEY (MATRICULA_P) 7 REFERENCES "PAIS"(MATRICULA_P) ON DELETE CASCADE);

Após criarmos as tabelas da nossa aplicação, devemos então executar o Delphi.

A aplicação será desenvolvida em duas partes:

Parte 1 – Criação dos componentes necessários;Parte 2 – Explicação do código gerado para cada componente criado.

5���� �"�������������� !��������������:���

���!�� �"������������ �����#��� �����

Um novo Datamodule deve ser adicionado ao projeto. Vá em File->New->DataModule.

Os seguintes valores deverão ser modificados:

Page 202: Delphi 6 com Oracle

204 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

������ ��

O DataModule deverá ser salvo como udmexemplo5.pas.

���!����"�8���������)������� !������������;��8#/���#��� �����

Conforme figura 11.3, quatro componentes deverão ser adicionados:

������ �$

1

3

2

4

Page 203: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 205

Os seguintes valores deverão ser modificados:

1 – TADOConnection

������ �%

Page 204: Delphi 6 com Oracle

206 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

2 – TADODataSet 4 – TADOCommand

������ �( ������ �-

3 – TDataSource

������������ � �+

Page 205: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 207

���!��$�"������������� ��:���!����!������������������������ !�������Uma vez criados os componentes no TDataModule, deveremos, então, criar o pa-gecontrol, assim como 3 tabsheets que deverão ter sua propriedade caption modifi-cada para Pais, Filhos e Consulta conforme mostra a figura 11.8.

������ ��

���!��$� �"������������� !�������������;�&���

������ �.

PageControl

Tabsheet1 Tabsheet2

Tabsheet3

Tabsheet1

2

3

1

4

Page 206: Delphi 6 com Oracle

208 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TEdit

��������������� ��� � � G ���������������� � �

2 – TEdit

�������������� �

Page 207: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 209

4 – TButtons

Nos componentes TButtons criados, deveremos modificar a propriedade name paraButton1, Button2,...,Button7, seguindo a ordem da esquerda para a direita.

A propriedade caption de cada um deve ser alterada conforme a figura 11.9.

���!��$���"������������� !�������������;�&����

������ � $

Tabsheet2

1

23

4

5

Page 208: Delphi 6 com Oracle

210 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TEdit

��������������� ��� � � %������ ������������������ � +

2 – TEdit 4 – TEdit

������ � ( ������������ � � -

Page 209: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 211

5 – TButtons

Nos componentes TButtons criados, deveremos modificar a propriedade name paraButton8, Button9,...,Button14, seguindo a ordem da esquerda para a direita.

A propriedade caption de cada um deve ser alterada conforme a figura 11.13.

���!��$�$�"������������� !�������������;�&���$

������ � �

Tabsheet3

1

2

3

45

6

7

89

10

Page 210: Delphi 6 com Oracle

212 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Os seguintes valores deverão ser modificados:

1 – TDBGrid 3 – TRadioButton

�������������������� � . ����������� � �������������� ��

2 – TGroupBox 4 – TRadioButton

������ ��G ���������� � ���

Page 211: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 213

5 – TEdit 7 – TRadioButton

���������������� ��$ �� ���������� � ��(

6 – TGroupBox 8 – TRadioButton

���������������� ��% ���������� � ��+

Page 212: Delphi 6 com Oracle

214 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

9 – TEdit

���������������� ��-

10 – TButtons

Nos componentes TButtons criados, deveremos modificar a propriedade name paraButton15 e Button16, seguindo a ordem da esquerda para a direita. A propriedadecaption de cada um deve ser alterada conforme a figura 11.18.

5������"��C!������������?�����������!��������� !������������Antes de iniciarmos a explicação sobre o funcionamento de cada tabsheet, algumasprocedures e funções de uso geral do projeto devem ser criadas.

A procedure a seguir é responsável por limpar os componentes contidos em cadatabsheet:

procedure TForm1.limpacomponentes;var ind: integer;begin for ind:= 0 to ComponentCount-1 do begin if components[ind] is tedit then (components[ind] as tedit).clear; end;end;

Page 213: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 215

Conforme o exemplo com os componentes da aba dbExpress, precisaremos de umaprocedure que inicie uma transação. Caso contrário, todas as alterações feitas comcomandos SQL (INSERT, UPDATE e DELETE) serão automaticamente atualiza-das no banco de dados Oracle.

A procedure a seguir verifica se existe alguma transação em aberto e, caso nãoexista, inicia uma nova.

procedure TForm1.iniciatransacao;begin with datamodule2.adoconnection1 do begin if not InTransaction then begintrans; end;end;

As instruções SQL de inclusão, exclusão e alteração serão executadas no ADO-Command1, a procedure a seguir evita a replicação de código em nosso projeto,bastando para isso que passemos como parâmetro a instrução SQL desejada.

procedure TForm1.executasql(stringsql: string);begin with datamodule2.adocommand1 do begin commandtype:= cmdtext; commandtext:= stringsql; execute; end;end;

Para que todas as modificações realizadas nas tabelas em nosso banco de dadosreflitam nos dbgrids do projeto, é necessário fechar e abrir, logo em seguida, oADODataSet associada a ele. A procedure listada logo adiante será responsável poressa tarefa.

procedure TForm1.executarefresh;begin with datamodule2.adodataset1 do begin limpacomponentes; close; commandtype:= cmdtext; if pagecontrol1.ActivePage = tabsheet1 then begin commandtext:= 'select * from pais order by 2'; open; end else if pagecontrol1.ActivePage = tabsheet2 then commandtext:= 'select b.matricula_f, b.nome, a.matricula_p, a.nome '+ 'from filho b, pais a '+ 'where a.matricula_p = b.matricula_p '; open; end else if pagecontrol1.ActivePage = tabsheet2 then datamodule2.ADODataSet1.Close; end;end;

Page 214: Delphi 6 com Oracle

216 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

As etapas a seguir mostrarão o ‘funcionamento’ de cada tabsheet, assim como oseventos referentes ao formulário, pagecontrol e a cada botão.

���!�� �"��� ��:���!����!���H�� I

É o formulário do nosso projeto, onde estão contidos todos os componentes.

Evento: OnActivateCódigo: procedure TForm1.FormActivate(Sender: TObject); var stringsql: string; begin pagecontrol1.activepage:= tabsheet1; stringsql:= 'select * from pais'; executasql(stringsql); limpacomponentes; pinclui:= false; end;

Objetivo: Inicializar nosso projeto, definindo a tabsheet1 como ativa, limpandoos componentes e executando o comando SQL para exibir os dados da tabelaPAIS.

���!����"�5���������É o componente que contém todas as tabsheets de nosso projeto.

Evento: OnChangeCódigo: procedure TForm1.PageControl1Change(Sender: TObject); begin executarefresh; limpacomponentes; end;

Objetivo: Verifica qual a tabsheet que está ativa, atualizando os dados no dbgridcorrente, através da procedure executarefresh e, em seguida, limpa os componentesda tela.

���!��$�"�,�;�&��� �H������������������:���I

1 – DbGrid1Exibir informações da tabela PAIS, através da ADODataSet1.Evento: Não existe.

Page 215: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 217

2 – EdtMatricpArmazenar em memória o número da matrícula do pai a ser inserida ou alterada atéque possa ser transferida para o banco de dados.Evento: Não existe.

3 – EdtNomepArmazenar em memória o nome do pai a ser inserido ou alterado.Evento: Não existe.

6 – Button1Colocar a tabsheet1 em condições de inserir informações em seus componentes,para transferi-las posteriormente para o banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button1Click(Sender: TObject); begin iniciatransacao; pinclui:= true; edtmatricp.enabled:= true; edtmatricp.SetFocus; end;

Objetivo: Caso não exista nenhuma transação ativa, a procedure inciatransacaoiniciará uma. Alterar o valor da variável global pinclui, informando que na tabelasPAIS um novo registro será inserido.

NO TA: Em todos os botões contidos nas tabsheets de nosso projeto a procedureiniciatransação está presente, executando a mesma função, conforme o exemplocom os componentes da aba dbExpress. Dessa forma, não será mais explicada afunção da mesma.

4 – Button2A exclusão deve permitir que um pai e seus respectivos relacionamentos sejamapagados, através da constraint criada.

Evento: OnClickCódigo: procedure TForm1.Button2Click(Sender: TObject); var stringsql: string; begin try iniciatransacao; stringsql:= 'delete from PAIS where MATRICULA_P = '+#39; stringsql:= stringsql +datamodule2.ADODataSet1['MATRICULA_P']+#39;

Page 216: Delphi 6 com Oracle

218 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

executasql(stringsql); except showmessage('Não foi possível excluir esse pai !'); end; executarefresh; end;

Objetivo: Utilizando o registro corrente do ADODataSet1, excluir o registro natabela PAIS e seu relacionamento na tabela FILHO. Em seguida, um refresh é exe-cutado para que a exclusão reflita no dbgrid.

4 – Button3Deve ser capaz de modificar as informações contidas nos componentes pertencen-tes a tabsheet1.

Evento: OnClickCódigo: procedure TForm1.Button3Click(Sender: TObject); begin iniciatransacao; pinclui:= false; edtmatricp.Text:= datamodule2.ADODataSet1['MATRICULA_P']; edtnomep.Text:= datamodule2.ADODataSet1['NOME']; edtmatricp.enabled:= false; edtnomep.SetFocus; end;

Objetivo: Os valores dos campos da tabela PAIS, contidos no registro corrente daADODataSet1 serão transferidos para a propriedade text dos componentes databsheet1. Alterar o valor da variável global pinclui, informando que o registro seráalterado. Mudar o valor da propriedade enabled para false no componente edtma-tricp, pois o valor da chave primária não pode ser alterado.

4 – Button4Responsável por transferir as informações contidas nos componentes da tabsheet1para o banco de dados Oracle, alterando ou inserindo um registro.

Evento: OnClickCódigo: procedure TForm1.Button4Click(Sender: TObject); var stringsql: string; begin if pinclui then begin try stringsql:= 'insert into pais values ('+#39; stringsql:= stringsql + edtmatricp.text +#39+', '+#39; stringsql:= stringsql + edtnomep.text +#39+')'; executasql(stringsql);

Page 217: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 219

except showmessage('Não foi possível incluir esse pai !'); end; end else begin try stringsql:= 'update pais set NOME = '+#39; stringsql:= stringsql + edtnomep.text +#39+' where '; stringsql:= stringsql + 'MATRICULA_P = '+#39+edtmatricp.text +#39; executasql(stringsql); except showmessage('Não foi possível alterar esse pai !'); end; end; executarefresh; panel1.Enabled:= false; end;

Objetivo: Através do valor da variável global pinclui, um comando SQL de inclu-são ou alteração deve ser executado, transferindo o conteúdo da propriedade text decada componente para a tabela PAIS1. Em seguida um refresh para que a atualiza-ção reflita no dbgrid.

4 – Button5Altera para permanente as atualizações pendentes em todas as tabelas do banco dedados.

Evento: OnClickCódigo: procedure TForm1.Button5Click(Sender: TObject); begin datamodule2.ADOConnection1.commitTrans; executarefresh; end;

Objetivo: Executar o método COMMITTRANS do componente TADOConnecti-on1 no banco de dados, finalizando a transação, e um refresh para que a atualiza-ção reflita no dbgrid.

4 – Button6Cancelar as atualizações pendentes em todas as tabelas do banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button6Click(Sender: TObject); begin

1 É importante lembrar que as atualizações efetuadas estão pendentes, como já foi explicado.

Page 218: Delphi 6 com Oracle

220 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

datamodule2.ADOConnection1.RollbackTrans; executarefresh; end;

Objetivo: Executar o método ROLLBACKTRANS do componente TADOConnec-tion1, finalizando a transação, no banco de dados e um refresh para que a atualiza-ção reflita no dbgrid.

���!����"�,�;�&�����H��������������&��I

1 – DbGrid2Exibir informações da tabela FILHO, através do ADODataSet1.Evento: Não existe.

2 – EdtMatricfArmazenar em memória, até ser transferida para o banco de dados, a matrícula dofilho a ser inserida ou alterada.Evento: Não existe.

3 – EdtNomefArmazenar em memória, até ser transferido para o banco de dados, o nome do filhoa ser inserido ou alterado.Evento: Não existe.

4 – EdtMatricp2Armazenar em memória o número da matrícula do pai a ser inserida ou alterada atéque possa ser transferida para o banco de dados.Evento: Não existe.

5 – Button8A rotina de inclusão deve ser capaz de colocar a tabsheet2 em condições de inseririnformações nos componentes edtmatricf, edtnomef e edtmatricp2, que serão trans-feridas posteriormente para o banco de dados.

Evento: OnClickCódigo: procedure TForm1.Button8Click(Sender: TObject); begin iniciatransacao; pinclui:= true; edtmatricf.enabled:= true; edtmatricf.SetFocus; end;

Page 219: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 221

Objetivo: Alterar o valor da variável global pinclui, informando ao projeto que umnovo registro será inserido na tabela FILHO.

5 – Button9Deve ser permitido que um filho seja excluído da tabela FILHO.

Evento: OnClickCódigo: procedure TForm1.Button9Click(Sender: TObject); var stringsql: string; begin try iniciatransacao; stringsql:= 'delete from FILHO where MATRICULA_F = '+#39; stringsql:=stringsql+datamodule2.ADODataSet1['MATRICULA_F']+#39+' AND '; stringsql:= stringsql +' MATRICULA_P = '+#39; stringsql:= stringsql +datamodule2.ADODataSet1['MATRICULA_F']+#39; executasql(stringsql); except showmessage('Não foi possível excluir esse filho !'); end; executarefresh; end;

Objetivo: Excluir o registro na tabela FILHO, utilizando o registro corrente doADODataSet1, executando logo em seguida um refresh para que a exclusão reflitano dbgrid.

5 – Button10A rotina de alteração deve ser capaz de colocar a tabsheet2 em condições de modi-ficar a informação contida no componente edtnomef.

Evento: OnClickCódigo: procedure TForm1.Button10Click(Sender: TObject); begin iniciatransacao; pinclui:= false; edtmatricf.Text:= datamodule2.ADODataSet1['MATRICULA_F']; edtmatricp2.Text:= datamodule2.ADODataSet1['MATRICULA_P']; edtnomef.Text:= datamodule2.ADODataSet1['NOME']; edtmatricf.enabled:= false; edtmatricp2.enabled:= false; edtnomef.SetFocus; end;

Objetivo: Transferir para a propriedade text dos componentes edtmatricf, edtnomefe edtmatricp2 os valores dos campos MATRIC_F, NOME e MATRIC_P, contidosno registro corrente do ADODataSet1. Em seguida, alterar o valor da variável glo-

Page 220: Delphi 6 com Oracle

222 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

bal pinclui, informando ao projeto que o registro será alterado na tabela FILHO.Por fim, alterar o valor da propriedade enabled para false nos componentes edtma-tricp2 e edtmatricf, pois não devemos alterar o valor da chave primária.

5 – Button11A rotina do botão Ok é responsável por transferir as informações contidas noscomponentes da tabsheet2 para o banco de dados Oracle, alterando ou inserindoum registro na tabela FILHO.

Evento: OnClickCódigo: procedure TForm1.Button11Click(Sender: TObject); var stringsql: string; begin if pinclui then begin try stringsql:= 'insert into filho values ('+#39; stringsql:= stringsql + edtmatricf.text +#39+', '+#39; stringsql:= stringsql + edtmatricp2.text +#39+', '+#39; stringsql:= stringsql + edtnomef.text +#39+')'; executasql(stringsql); except showmessage('Não foi possível incluir esse filho !'); end; end else begin try stringsql:= 'update filho set NOME = '+#39; stringsql:= stringsql + edtnomef.text +#39+' where '; stringsql:= stringsql+'MATRICULA_F = '+#39+edtmatricf.text +#39+ ' AND '; stringsql:= stringsql + 'MATRICULA_P = '+#39+edtmatricp2.text +#39; executasql(stringsql); except showmessage('Não foi possível alterar esse filho !'); end; end; executarefresh; panel2.Enabled:= false; end;

Objetivo: Através da variável global pinclui, verificar se um comando SQL deinclusão ou alteração deve ser executado, transferindo a informação contida napropriedade text de cada componente para a tabela FILHO2. Em seguida, executarum refresh para que a atualização reflita no dbgrid.

2 É importante lembrar que as atualizações efetuadas estão pendentes, como já foi explicado.

Page 221: Delphi 6 com Oracle

Conexão com o Banco de Dados Oracle via ADO • 223

5 – Button12Fica a cargo dessa rotina tornar permanentes as atualizações pendentes em todas astabelas do banco de dados.

Evento: OnClickCódigo: Deve apontar para o evento Onclick do Button5.

Objetivo: Executar o método COMMITTRANS do componente TADOConnecti-on1 no banco de dados, finalizando a transação, e um refresh para que a atualiza-ção reflita no dbgrid.

4 – Button13Esta rotina, ao contrário da anterior, cancela as atualizações pendentes em todas astabelas do banco de dados.

Evento: OnClickCódigo: Deve apontar para o evento Onclick do Button6.

Objetivo: Executar o método ROLLBACKTRANS do componente TADOConnec-tion1, finalizando a transação, no banco de dados e um refresh para que a atualiza-ção reflita no dbgrid.

���!��$�"�,�;�&���$�H�������������!��������!���������&�������������I20 – Button36Gerar a consulta para um funcionário e seus respectivos filhos, em função dos valo-res informados nos componentes contidos na tabsheet3.

Evento: OnClickCódigo: procedure TForm1.Button15Click(Sender: TObject); var pselect, pfrom, pwhere, stringsql: string; begin pselect:= 'select b.matricula_f, b.nome, a.matricula_p, a.nome '; pfrom:= 'from filho b, pais a '; pwhere:= 'where a.matricula_p = b.matricula_p ';

if rbpaisel.checked then pwhere:= pwhere + 'and a.matricula_p = '+#39+edtmatricp3.Text+#39;

if rbfilhosel.checked then pwhere:= pwhere + 'and b.matricula_f = '+#39+edtmatricf2.Text+#39;

Page 222: Delphi 6 com Oracle

224 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

stringsql:= pselect+pfrom+pwhere; with datamodule2.ADODataSet1 do begin try close; commandtype:= cmdtext; commandtext:= stringsql; open; except showmessage('Não foi possível realizar a consulta !'); end; end; end;

Objetivo: Criar uma consulta, utilizando as tabelas PAIS e FILHOS, através de 3variáveis, que irão compor o comando SELECT. Sendo elas:

• pselect – Escolhe os campos que serão exibidos pela consulta;• pfrom – Seleciona as tabelas da consulta;• pwhere – Seleciona a condição da consulta.

A consulta é gerada seguindo os exemplos anteriores, ou seja, cada variável recebeum valor inicial, que pode ser concatenado com outro, variando conforme a escolhade alguma opção da tela de consulta. Ao final, seus valores serão somados em umaúnica variável: stringsql.

Page 223: Delphi 6 com Oracle

225

Parte V.Apêndices

Page 224: Delphi 6 com Oracle

227

Apêndice A.Dicas para o Delphi

5�!�������!�!��O banco de dados Oracle, ao realizar um comando SELECT, realiza uma estratégiapara executar essa consulta, verificando sua sintaxe e determinando como utilizaros índices e outras técnicas de acesso.

A preparação inicial da estratégia de acesso da consulta pode ser forçada utilizandoo método Prepare de um componente Query. Se a consulta for executada váriasvezes, ela estará mais rápida, pois todas as operações iniciais já foram executadasde uma só vez. Note que o método Prepare deve ser chamado novamente caso otexto SQL da consulta mude. O método Unprepare deve ser chamado ao final, paraliberar alguns recursos do BDE.

�20�B�����Conforme visto no capítulo 7, a linguagem SQL possui muitos comandos em rela-ção às instruções SELECT . Para facilitar o desenvolvimento de instruções SQLcorretas, o Delphi Client/Server possui uma ferramenta chamada SQL Builder, queé facilmente ativada através de um clique com o botão direito do mouse em umcomponente Query, conforme nos mostra a figura A.1.

Em seguida, serão solicitados o nome e a senha do usuário que irá se conectar aobanco de dados Oracle.

A utilização do SQL Builder é muito simples, onde, após a conexão, devemos sele-cionar uma ou mais tabelas com que iremos trabalhar e que serão colocadas na áreade trabalho.

Page 225: Delphi 6 com Oracle

228 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

������8�

Ao selecionar os parâmetros corretos, conforme será explicado a seguir, o comandoQuery -> Run Query (ou F9) permite ver o resultado da consulta ou o comandoQuery -> Show SQL (F7) para ver o código-fonte da instrução select que foi gera-da.

A figura A.2 nos mostra os principais botões, assim como os recursos do QueryNotebook.

A seguir serão comentadas as páginas do Query Notebook:

� Criteria – indica os critérios de seleção da cláusula where. Ao selecionar umdos campos da tabela de resultados, você pode indicar uma comparação comrelação a um valor fixo ou outro campo, podendo usar LIKE, IS NULL,BETWEEN, etc. Essa página permite combinar várias condições com osoperadores AND, OR e NOT.

� Selection – lista todos os campos do conjunto de resultado e permite que vocêlhes forneça um alias. Funções agregadas podem ser adicionadas (SUM, AVG,etc.). A caixa de seleção no canto superior esquerdo indica a condiçãoDISTINCT.

� Grouping – corresponde à cláusula GROUP BY.

� Group Criteria – corresponde à cláusula HAVING.

� Sorting – corresponde à cláusula ORDER BY.

� Joins – é a última, porém a mais poderosa, pois permite que você defina condi-ções de junção, além do simples arrastamento de um campo de uma tabela paraoutra na área de trabalho.

Ao fecharmos a janela, o SQL Builder pergunta se o SQL gerado será transportadopara o conteúdo da propriedade STRINGS do componente QUERY.

Page 226: Delphi 6 com Oracle

Apêndice A: Dicas para o Delphi • 229

Mostra o texto SQL gerado

Executa o comando SQL Seleciona as tabelas

Seleciona o banco de dados

Campos que

serão

exibidos

Área de trabalho

Query Notebook

Critério de seleção

������8��

#;����O banco de dados Oracle trabalha com conjuntos de dados lógicos, que não estãorelacionados a uma ordem física. Os dados são manipulados conforme um modelomatemático baseado na teoria dos conjuntos, o modelo relacional.

As linhas de uma tabela, nesse mo delo, são identificadas através de uma chaveprimária e não pela sua posição. Quan do um conjunto de linhas for obtido, obanco de dado s Oracle inclui em cada uma delas uma referência à seguinte,tornando rápida a mudança de uma linha a outra, mas terrivelmente lenta avolta à linha anterior. É comum dizer que o banco de dados Oracle utiliza umcursor unidirecional.

Page 227: Delphi 6 com Oracle

230 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Ao navegarmos para trás num dbgrid, a performance do banco cairá sensivelmente.O BDE, nessa hora, ajuda muito, pois mantém em um cache local as linhas já car-regadas da tabela. Assim, quando nos movemos para as linhas seguintes do nossodbgrid, elas são solicitadas ao banco de dados Oracle, mas quando voltamos, oBDE entra em ação e fornece as linhas, tornando os cursores bidirecionais, emboraisso possa utilizar muita memória da estação cliente.

Dessa forma, é melhor filtrarmos parte dos registros a serem exibidos ou utilizar-mos tabelas pequenas num dbgrid em aplicações cliente/servidor.

6���������Se voltar linhas num dbgrid pode acarretar em perda de performance do banco dedados Oracle, pular para a última linha de uma tabela é ainda pior; pois essa opera-ção, normalmente, busca todas as linhas.

Podemos ilustrar essa situação com a utilização da propriedade RecordCount, ondecalcular o número total de linhas de uma tabela de registros freqüentemente implicaem movê-las todas para a estação cliente. Então, como solução para obter o númerototal de linhas de uma tabela, utilize a função count(*), como nos mostra o exemploa seguir:

SELECT COUNT(*)FROM EMPREGADOS;

�������� �������!�����������Ao desenvolvermos uma aplicação, contendo um componente Database, toda vezque vamos nos conectar no banco de dados Oracle, sempre é solicitado o nome dousuário e a sua senha. Essa tarefa de informar toda vez o nome do usuário e res-pectiva senha pode se tornar cansativa e, principalmente, improdutiva.

Esse problema pode ser resolvido de duas formas.

Na primeira forma pode-se:

� alterar a propriedade Loginprompt para false;� alterar a string de parâmetros da propriedade Params, como mostra a figu-

ra A.3:

Page 228: Delphi 6 com Oracle

Apêndice A: Dicas para o Delphi • 231

������8�$

Na segunda, podemos:

� Criar para nossa aplicação uma caixa de login personalizada, onde será ne-cessário informar apenas uma vez o nome do usuário e a senha, como nosmostra a figura A.4:

edtusuário

edtsenha

������8�%

Devemos colocar no evento OnLogin do componente Database o seguinte código:

Procedure TForm1.Database1Login(Database: TDatabase; LoginParams: TStrings);Begin

Form1:= TForm1.create(app1ication);

Page 229: Delphi 6 com Oracle

232 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

with Form1 do begintry if ShowModal = mrOK then begin

LoginParams.Values[‘USER NAME’]:= edtusario.text; LoginParams.Values[‘PASSWORD’]:= edtSenha.text;

end else begin

Application.Terminate; end;finally free;

end; End;

Ao clicarmos no botão Ok, os valores contidos nas propriedades text dos edits sãopassados para os parâmetros de login do Database.

�������� ����������B#��� ��� !�����C������A função DBIAddAlias, permite adicionar um alias permanente à configuração doBDE. Para podermos utilizar essa função, devemos adicionar a unit BDE à cláusulaUSES. A função a seguir adiciona um alias ao BDE, bastando que seja passadocomo parâmetro apenas o nome do alias.procedure crianovoalias(nomealias: string);begin dbiinit(nil); dbiaddalias(nil,pchar(nomelias),pchar('ORACLE'),nil, true); dbiexit;end;

Em contrapartida, para removermos um alias em tempo de execução do BDE, de-vemos utilizar a função DBIDeleteAlias, como mostra a função a seguir:procedure apagaalias(nomealias: string);begin dbiinit(nil); dbideletealias(nil,pchar(nomelias)); dbiexit;end;

Page 230: Delphi 6 com Oracle

233

Apêndice B.Dicas para o Oracle

,� ��&�����B�����Os blocos de dados são a menor unidade de entrada e saída. Seu tamanho é defini-do, através do parâmetro DB_BLOCK_SIZE, ao criarmos um banco de dados, enão pode ser alterado após sua criação.

Como padrão, o Oracle define que o tamanho de bloco para o banco será de 2K.Esse tamanho é muito eficiente em bancos de dados do tipo transacional, mas ine-ficaz quando tratamos de bancos de dados do tipo datawarehousing, que devem tertamanhos de blocos de 8K.

Em função do exposto, as características de cada banco de dados (transacional,híbridos ou datawarehousing) devem ser analisadas com muito cuidado para queseja definido o tamanho do bloco de dados a ser utilizado, pois uma escolha infeliz,blocos de 2K para bancos do tipo datawarehousing, fará com que o banco de dadostenha perda de performance.

�' ��������� ���������6���;��JO header de um segmento de rollback contém uma tabela de transações que define oestado de cada transação. Toda transação que usa um segmento de rollback necessitaatualizar freqüentemente essa tabela, podendo ocasionar contenção no header, espe-cialmente em bancos do tipo transacionais, que utilizam pequenas transações.

Então, para bancos de dados do tipo transacional são recomendados muitos, porémpequenos, segmentos de rollback e, se possível, criar um segmento de rollbackpara 4 transações concorrentes.

Para banco de dados do tipo batch, crie poucos segmentos, porém grandes.

Page 231: Delphi 6 com Oracle

234 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

7����!��C����������������������0�������Ao criarmos nosso banco de dados Oracle, através da instalação default, os arqui-vos de control file (necessário para o banco iniciar e funcionar corretamente) e logfile (responsável, basicamente, por reduzir a perda de dados) estão duplicados, sóque no mesmo disco físico, o que representa perigo em caso de falha da mídia.

Por uma questão de segurança, mantenha-os em discos separados, pois caso hajaalgum problema em um dos discos, os arquivos estarão seguros no outro.

Problema físico no disco

Cópia de segurança

������B �

5���������������������,�;����O banco de dados Oracle utiliza, fisicamente, os datafiles e, logicamente, astablespaces para armazenar os dados do banco e as tabelas. Ao criarmos nossobanco, por padrão, todas as tabelas que forem sendo adicionadas posteriormentepor futuras aplicações serão armazenadas, logicamente, na tablespace SYSTEM efisicamente num datafile criado pelo banco na ocasião da instalação.

Permanecendo o banco com essa configuração padrão, CERTAMENTE teremosproblemas futuros, pois ao criarmos e apagarmos constantemente tabelas, que esta-rão sendo criadas na tablespace SYSTEM, teremos uma perda enorme a nível deperformance, além de gerarmos fragmentação de espaço livre, e, num possíveldescuido, o banco precisará ser reinstalado.

Então, ao criarmos nosso banco, a primeira tarefa a ser realizada é adicionar umatablespace para armazenar os dados da aplicação e definir que os usuários do ban-co devem utilizá-la.

Page 232: Delphi 6 com Oracle

235

Índice Remissivo

8

ActiveX Data Objects, 197ADO, 197alias, 55, 232Aritméticos, 43

B

BDE, 232BDE Administrator, 54BFILE, 27BLOB, 27blocos de dados, 233

�Caract ere, 45Caract eres, 43CHAR(N), 27cliente, 5cliente/servidor, 5CLOB, 27Close, 200, 201CommandText, 200CommandType, 200COMMIT, 39Comparação, 43comunicação, 7Configuration, 56

Connected, 197Connection, 199, 200ConnectionString, 198ConnectionTimeOut, 198constraints, 22Constraints

criação, 30remoção, 30

control file, 234CursorLocation, 198, 199, 200CursorType, 199, 201

#

Dadosalterando, 37apagando, 36inserindo, 35

Databases, 56Datamodule, 64, 98DATE, 27dbExpress, 153Dbgrids, 229DCL, 34DDL (Data Definition Language), 26DELETE CASCADE, 25Delphi-ADO, 202Delphi-BDE, 62DML, 34

Page 233: Delphi 6 com Oracle

236 • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

ExecSql, 200

FOREIGN KEY, 24, 153

K

host, 14

1

Índices, 31alteração, 32criação, 31recriando, 33remoção, 33

instância, 14IP, 14

0

log file, 234Lógicos, 43login, 230LoginPrompt, 198LONG, 27

7

MarshalOptions, 199, 201Mode, 198

Net8 Easy Config, 11NOT NULL, 22

NUMBER(N,D), 27

/

OLE DB, 197Open, 200, 201Operadores, 42Oracl e, 14, 62, 202

5

pagecontrol, 67PageControl, 176, 216pfrom, 195pgroup, 195Prepare, 227PRIMARY KEY, 24procedures, 80protocolo de comunicação, 13pselect, 195pwhere, 195

2

Querys, 61

6

RAW(N), LONG RAW, 27RecordCount, 230rollback, 233ROWID, 27

Servidores, 6SET, 43SID, 14SQL, 19, 200SQL Builder, 227SQL8 Plus, 20

Page 234: Delphi 6 com Oracle

Índice Remissivo • 237

,

Tabelas, 26alteração, 28criação, 27remoção, 29

Tables, 61tablespace, 234TADOCommand, 201TADOConnection, 197TADODataSet, 200TADOQuery, 199TDatabase, 58TDatasource, 61, 153, 202TQuery, 59transação, 53

TSQLClientDataSet, 152TSQLConnection, 148TSQLDataSet, 150TSQLQuery, 151TUpdateSql, 60, 97

UNIQUE KEY, 23Unprepare, 227UPDATE, 38

VARCHAR2(N), 27

Page 235: Delphi 6 com Oracle

1�������� �������������������������������� �������������������������������� �������������������������������� ���

586,�� ��862�1,�,�68��01��,�E��6�1#/6 �������������������������������� $

������������B:����� �������������������������������� �������������������������������� ������������������ (Clientes ......................................................................................................... 5Servidores ...................................................................................................... 6Comunicação.................................................................................................. 7Vantagens ...................................................................................................... 8

586,��11���/��19�68LM���#/��01��,��#/�B8��/�#�586,��11�� #8#/��/68�0� �������������������������������� �������������������������������� ����� .

�������� �������������������������������� �������������������������������� �������������������������������� ��� Utilizando o Net 8 Easy Config .........................................................................11Criando um Novo Serviço ................................................................................12

586,��111���20 �������������������������������� �������������������������������� ������������������������� -

$���������� �������������������������������� �������������������������������� �������������������������������� � .

%����������������20���5��� �������������������������������� �������������������������������� ����� �G

(��1�������������#���� �������������������������������� �������������������������������� ���������� ��NOT NULL ..................................................................................................22UNIQUE KEY...............................................................................................23PRIMARY KEY............................................................................................23FOREIGN KEY.............................................................................................24

Cláusula DELETE CASCADE.....................................................................24

+��#����#����������0��������H##0I �������������������������������� ���������������������� �+Tabelas.........................................................................................................26

Tipos de Dados..........................................................................................27

Page 236: Delphi 6 com Oracle

X • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Criação.....................................................................................................27Alteração..................................................................................................28Remoção ..................................................................................................29Criação de constraints .................................................................................30Remoção de constraints ...............................................................................30

Índices..........................................................................................................31Criação.....................................................................................................31Alteração..................................................................................................32Remoção ..................................................................................................32Recriando um índice...................................................................................33

-��#����7���!��������0��������H#70I���#�����������0�����������H#�0I �������������������������������� �������������������������������� �������������������������������� ������� $%

DML............................................................................................................34DCL ............................................................................................................34Inserindo, Apagando e Alterando Dados em uma Tabela........................................35

Inserindo Dados .........................................................................................35Apagando Dados ........................................................................................36Alterando Dados ........................................................................................37

Estado dos Dados ...........................................................................................38Transformando as Mudanças Pendentes em Permanentes ...................................39Cancelando as Mudanças Pendentes...............................................................39

Selecionando Dados de uma Tabela ...................................................................39Operadores ....................................................................................................42

Aritméticos ...............................................................................................43Caract eres .................................................................................................43Comparação..............................................................................................43Lógicos ....................................................................................................43SET ........................................................................................................43

Funções ........................................................................................................44Funções de Linha.......................................................................................44Funções de Grupo ......................................................................................46

Selecionando Dados de Múltiplas Tabelas ...........................................................48Definindo Aliases para Tabelas .....................................................................48

586,��1���1�,�968�#/�#�05K1��/7�/68�0� �������������������������� (

���,�����A�� �������������������������������� �������������������������������� ���������������������������� ($

.������C����� ���B��������#�����/��������B#� ������������������������� (%BDE Administrator.........................................................................................54

Utilizando o BDE Administrator...................................................................54Configurando o BDE Administrator...............................................................55

Componentes Referentes a Conexão...................................................................58TDatabase.................................................................................................58TQuery ....................................................................................................59

Page 237: Delphi 6 com Oracle

Sumário • XI

TUpdateSql ..............................................................................................60TDatasource..............................................................................................61

Tables X Querys ............................................................................................61Vantagens/Desvantagens .............................................................................61

Exemplos Delphi-BDE X Oracle .......................................................................62Construindo uma Aplicação com TQuery........................................................63Parte 1 – Criação dos Componentes Necessários ..............................................64Parte 2 – Explicação do Código Gerado para Cada Componente Criado................80Construindo uma aplicação com TUpdateSql ..................................................97Parte 1 – Criação dos componentes necessários ................................................98Parte 2 – Explicação do código gerado para cada componente criado.................. 129

G������C����� ���B��������#�����/���������;�C!��� ���������� %�Componentes Referentes a Conexão................................................................. 148

TSQLConnection..................................................................................... 148TSQLDataSet.......................................................................................... 150TSQLQuery............................................................................................ 151TSQLClientDataSet.................................................................................. 152TDatasource............................................................................................ 153

Exemplo Delphi-dbExpress com Oracl e............................................................ 153Parte 1 – Criação dos componentes necessários .............................................. 155Parte 2 – Explicação do código gerado para cada componente criado.................. 173

������C����� ���B��������#�����/��������8#/ �������������������� .-Componentes Referentes a Conexão................................................................. 197

TADOConnection.................................................................................... 197TADOQuery ........................................................................................... 199TADODataSet ......................................................................................... 200TADOCommand ..................................................................................... 201TDatasource............................................................................................ 202

Exemplo Delphi-ADO com Oracl e................................................................... 202Parte 1 – Criação dos componentes necessários .............................................. 203Parte 2 – Explicação do código gerado para cada componente criado.................. 214

586,�����85N�#1��� �������������������������������� �������������������������������� ���������� ��(

8!O������8��#�����!�����#��!&� �������������������������������� ������������������������ ��-Prepare e Unprepare...................................................................................... 227SQL Builder................................................................................................ 227Dbgrids ...................................................................................................... 229RecordCount ............................................................................................... 230Criando um login personalizado ...................................................................... 230Criando um alias no BDE em tempo de execução................................................ 232

8!O������B��#�����!�����/���� �������������������������������� ������������������������ �$$Tamanho de Blocos ...................................................................................... 233

Page 238: Delphi 6 com Oracle

XII • Criando Aplicações em DELPHI 6 com Banco de Dados ORACLE

Número de Segmentos de Rollback.................................................................. 233Multiplexação de Control File e Log File.......................................................... 234Perigo na Construção de Tabelas ..................................................................... 234

<������6� ����� �������������������������������� �������������������������������� �������������������� �$(