Tutorial - Consultas (ADOQuery)

Propaganda
UNEB - LP II – Delphi
Professora Lucélia
Delphi com Acesso a Banco de Dados
Trabalhando com ADOQUERY
O componente Query é um componente dataset, assim como o Table, especializado em
conexões com tabelas. A diferença entre eles está na forma como acessam as informações. O
Table liga-se diretamente a uma única tabela, através da propriedade TableName. O Query faz
suas ligações através da linguagem SQL, o que lhe possibilita o acesso a várias tabelas. O
Query também possui métodos mais eficientes de acesso aos recursos do servidor do que o
Table. Além de fazer uso de uma linguagem mais eficiente, permite o servidor processar
requisições mais rapidamente e com menos tráfego de rede.
Os exemplos conduzidos por este material serão baseados em um banco de dados Access
contendo duas tabelas: Produto e Categoria. As mesmas usadas no material “Uso do
Componente ADOConnection”. Mostraremos novamente o modelo e as especificações de tabelas
a seguir:
Fig. 1 – modelo de dados do cadastro de produtos
1) Criando o Banco de Dados
Para definir o banco de dados, usaremos o SGBD Access da Microsoft. Entre no programa, crie
um banco de dados vazio e salve em uma pasta Consprod.
a) Criação da Tabela Categoria
Selecione a opção Criar Tabela no Modo Estrutura e informe os seguintes dados na janela:
Chave
Nome do campo
Tipo de dados
Tamanho
codigo
descricao
Autonumeração
Texto
40
1
Salve a tabela com o nome “Categoria”. Abra a tabela Categoria no modo dados e informe os seguintes
valores para a coluna descricao: Limpeza, Alimentação, Vestuário e Bebidas. Para salvar um registro,
basta pressionar seta para baixo ou para cima. Observe que o codigo da Categoria é inserido
automaticamente assim que o registro é salvo.
b) Criação da Tabela Produto
Selecione a opção Criar Tabela no Modo Estrutura e informe os seguintes dados na janela:
Chave
Nome do
campo
codigo
Tipo de dados
nome
estoque
embalagem
frágil
Origem
Valor
codCat
Texto
Inteiro
Texto
Texto
Texto
Moeda
Inteiro Longo
Tamanho
Autonumeração
50
5
1
25
Salve a tabela com o nome “Produto”
2) Criando o Projeto CadProdutos
Entre no Delphi, selecione File  Save All e salve a unit como uProduto na pasta ConsProduto e em
seguida o projeto, como PConsProduto. Altere as seguintes propriedades do formulário:
• Name= FconsProduto
• Caption = Cadastro de Produtos
• Position=poScreenCenter.
3) Definindo o Módulo de Dados
Para criar o módulo de dados, acesse a opção File  New Data Module. Salve a unit como “UDM”. Em
seguida, altere o nome do Datamodule (propriedade name) para DM.
a) ADOConection
Insira um componente ADOConnection (paleta ADO) no data module e altere as seguintes propriedades
2

ConnectionString: Selecione a propriedade ConnectionString e clique nas reticências. Na janela
que se abrirá, verifique se a opção “Use Connection String” está marcada e clique no botão Build
para abrir a janela “Propriedade de Vinculação de dados”. Na orelha Provedor, selecione o driver
“Microsoft Jet 4.0 OLE DB Provider” e clique em avançar. Na aba Conexão clique nas reticências
do item 1 e selecione o banco de dados (consprod.mdb) que será acessado e clique em Ok.

Loginprompt: False (inibe a janela de senha do banco de dados)

Name: ADOConsProd (padrão ADO + nome_do_programa)

Connected: True
b) ADOQuery
Insira um componente ADOQuery (paleta ADO) e altere as seguintes propriedades
• Connection:
• Name:
selecione o nome do componente ADOConnection (ADOConsProd);
QrProd
c) Datasource
Insira um componente Datasource (paleta Data Access) e altere as seguintes propriedades
• Dataset:
• Name:
selecione o nome do componente ADOquery (QrProd);
DsConsProd
d) ADOTable
Insira um componente AdoTable (paleta ADO) e altere as seguintes propriedades
• Connection:
• Name:
selecione o nome do componente ADOquery (QrProd);
TBCat
• Tablename:
• Active:
Categoria
True
e) Datasource
Insira um componente Datasource (paleta Data Access) e altere as seguintes propriedades
• Dataset:
• Name:
TBCat;
DsCat
3
Seu data module deve estar semelhante ao da figura abaixo:
4
Exemplo 1
a) Torne o formulário FconsProd ativo. Em seguida, faça-o usar a unit do data module entrando na opção File 
Use Unit e selecionando Udm;
b) insira componente DBGrid (Data Controls) e altere a propriedade Datasource para DM.DsConsProd (nome do
datasource ligado ao query)
c) insira um botão no formulário, altere seu Caption para “Ver todos” e acrescente o seguinte código no seu evento
OnClick:
DM.QrProd.Close; // fecha o query
DM.QrProd.SQL.Clear; // apaga conteúdo da propriedade Sql
// adiciona o comando SQL
DM.QrProd.SQL.Add('SELECT * FROM produto');
DM.QrProd.Open; // executa o query
Execute o programa e clique no botão para ver o resultado abaixo:
Como você pôde perceber, o ADOquery é semelhante ao componente ADOtable no que diz respeito à conexão com
os componentes de acesso, pois ambos são datasets. Entretanto, todo ADOquery por padrão retorna um resultset
não editável.
Exemplo 2 – Consultas parametrizadas
Na maioria das situações, ao invés de consultarmos todos os registros de uma tabela, selecionamos apenas uma
parte deles, acrescentando uma cláusula WHERE em nosso comando SQL.
Entretanto, essa cláusula pode não requerer um valor fixo, mas algo variável provindo da interface com o usuário.
Nesse caso, chamamos esse valor de parâmetro. O parâmetro é identificado dentro do comando SQL colocando-se
um sinal de dois pontos ( : ) antes do nome de uma variável. Por exemplo:
WHERE nome = :cliente -> cliente é um parâmetro
WHERE salario > :valor -> valor é um parâmetro
Para exemplificar, iremos construir uma consulta que selecione todos os produtos que possuem uma determinada
origem. Ao verificarmos os registros da tabela Produto, vemos que a coluna “ORIGEM” pode assumir os seguintes
valores: São Paulo e Belo Horizonte. Baseado nisso, iremos inserir um componente de seleção na interface que
permita a escolha da origem.
a) Insira um label no form e altere seu Caption para “Origem”;
b) insira um Combobox (paleta Standard) e altere as seguintes propriedades:
• Name:
CbOrigem
• Items:
cada valor em uma linha: São Paulo e Belo Horizonte
Escreva o seguinte código no evento OnClick:
DM.QrProd.Close;
DM.QrProd.SQL.Clear;
DM.QrProd.SQL.Add(' SELECT * FROM produto ');
DM.QrProd.SQL.Add(' WHERE origem = :origem');
DM.QrProd.Parameters.ParamByName('origem').Value := CbOrigem.Text;
DM.QrProd.Open;
Nos comandos acima, vemos linhas semelhantes às do exemplo anterior. As mudanças ficam por conta das duas
linhas que fazem a inclusão e da passagem de um parâmetro.
A inclusão é determinada pela linha ..Add(‘ WHERE funcao = :origem’);, onde origem é o
parâmetro. Parâmetros devem ser imediatamente precedidos pelo caractere dois pontos. E a passagem do
5
parâmetro é feita na linha Parameters.ParamByName('origem').Value := CbOrigem.Text, onde
o parâmetro receberá o texto da opção selecionada no combobox.
A vantagem da utilização de parâmetros é que a cada consulta realizada, pode-se trocar o valor do parâmetro
informado e obter resultados diferentes.
6
Nota-se que o código do evento contém uma parte repetitiva representada pelo nome da query
(DM.QrProd). É possível utilizar o comando with do Delphi para evitar ter que escrever seu
nome em todas as linhas. Observe o mesmo código escrito com auxílio do comando with:
with DM.QrProd do
Begin
Close;
SQL.Clear;
SQL.Add(' SELECT * FROM produto ');
SQL.Add(' WHERE origem = :origem');
Parameters.ParamByName('origem').Value := CbOrigem.Text;
Open;
end;
Exemplo 3 – Parâmetros baseados em combos dinâmicas
No exemplo anterior, o campo função era representado por um combobox com os valores fixos. Veremos
agora como construir uma consulta parametrizada baseada em um campo de outra tabela que possui um
correspondente na tabela principal (chave estrangeira). Criaremos uma consulta que trará todos os
produtos de uma categoria informada. Só que ao invés de digitar o código da mesma, será disponibilizado
um combo para que seja selecionada a descrição.
a) Insira um label no form e altere seu Caption para “Categoria”;
b) insira um DbLookupCombobox (paleta Data Controls) e altere as seguintes propriedades:
• Name:
DblCategoria
• Listsource:
DM.DsCat
• Listfield:
descricao
• Keyfield:
codigo
Depois de ter ajustado essas propriedades, verifique se a seta para baixo do componente
DbLookupCombobox ficou habilitada. Se não estiver, confira se a propriedade Active do table DM.TbCat
está true. Não altere as propriedades Datasource e Datafield do componente. Estas só podem conter valor
se a interface for de entrada de dados.
Escreva o seguinte código no evento OnClick do DbLookupCombobox
with DM.QrProd do
begin
Close;
SQL.Clear;
SQL.Add(' SELECT * FROM produto ');
SQL.Add(' WHERE codcat = :cat');
Parameters.ParamByName('cat').Value :=
DM.TBcat.FieldByName('Codigo').Value;
Open;
end;
Podemos ver no código acima que o critério de seleção agora é determinado pelo campo codCat que
contém o código da categoria do produto. Como o Dblookup aponta diretamente para a tabela Categoria
(determinado pela sua propriedade Listsource), passamos o próprio valor do objeto field (codigo) para o
parâmetro
“cat”
na
linha
Parameters.ParamByName('cat').Value
:=
DM.TBcat.FieldByName('Codigo').Value;
7
Exemplo 4 – Trabalhando com parâmetros opcionais
Agora veremos como criar uma consulta onde o operador poderá efetuar a consulta informando a quantidade que
quiser de parâmetros. Se não informar nenhum, traremos todos os registros. Se informar algum, aplicamos aquele
filtro individualmente. A lógica consiste em testar se o operador informou algum valor no campo do parâmetro e
adicionar o respectivo filtro ao comando SQL. Prepararemos uma interface “especial” para separar este exercício
dos demais. Baseie-se na figura abaixo:
8
a) Insira um groupbox (paleta Standard) no form e altere seu Caption para “Parâmetros opcionais”;
b) insira um label e altere seu caption para “Nome”. Adicione também um Edit e altere:
• Name: EdNome
• Text: deixe em branco
c) insira um label e altere seu caption para “fragil”. Insira um Radiobutton altere seu nome para Rbnao e
seu Caption para “Não”. Insira um segundo Radiobutton ao lado do primeiro e altere seu nome para
RbSim e seu Caption para “Sim”
d) insira um DbLookupCombobox (paleta Data Controls) e altere as seguintes propriedades:
• Name: DblCat (para distinguir do outro DblCategoria que está na tela)
• Listsource: DM.DsCat
• Listfield: descricao
• Keyfield: codigo
e) insira um label e altere o Caption para “Preço (>que)”. Adicione também um Edit e altere:
• Name : EdValor
• Text: deixe em branco.
f) insira um Button e altere o Caption para “Pesquisar”
g) digite o seguinte trecho no evento OnClick do botão Pesquisar:
with DM.QrProd do
begin
Close;
SQL.Clear;
SQL.Add(' SELECT * FROM produto ');
SQL.Add(' WHERE 1=1 ');
//se tiver preenchido o nome, adiciona o filtro
if (EdNome.Text <> '') then
begin
SQL.Add(' AND nome like :nome ');
Parameters.ParamByName('nome').Value := '%'+EdNome.Text+'%';
end;
//se tiver marcado frágil sim
if (RbS.Checked) then
begin
SQL.Add(' AND fragil = "s" ');
end;
// se tiver marcado frágil não
if (RbN.Checked) then
begin
SQL.Add(' AND fragil = "n" ');
end;
// se tiver selecionado a categoria
if (DblCat.Text <> '') then
begin
SQL.Add(' AND codcat = :cat');
Parameters.ParamByName('cat').Value :=
DM.TBCat.FieldByName('Codigo').Value;
end;
// se tiver preenchido o preço, adiciona o filtro
if (EdValor.Text <> '') then
begin
SQL.Add(' AND valor > :val ');
Parameters.ParamByName('val').Value := StrToFloat(EdValor.Text);
end;
Open;
end;
end;
9
Logo no início, foi acrescentado o código “WHERE 1=1” no SQL. Essa condição foi colocada com uma
única finalidade: criar uma cláusula where fixa para o select. Isso evita repetidos testes para verificar se
o mesmo possui cláusula where antes de adicionar cada um dos filtros.
Observe que para cada teste realizado, é inserido um trecho referente ao filtro desejado através do comando
SQL.add() seguido da respectiva passagem de parâmetro. Isso permite que o operador tenha uma total flexibilidade
na escolha dos parâmetros da tela. É possível passar valores fixos também, como está sendo feito no caso do
campo frágil. No caso específico do filtro do campo nome, o recurso de passagem de parâmetros do Delphi não
suporta a delimitação dos coringas da cláusula LIKE (caractere “%”) no próprio comando, tendo que ser passados
na montagem do parâmetro, como pode ser verificado na linha Parameters.ParamByName('nome').Value :=
'%'+EdNome.Text+'%';
h) insira um Button e altere o Caption para “Nova Consulta”. Digite o seguinte trecho para evento
OnClick
EdNome.Clear;
EdValor.Clear;
DblCat.Keyvalue := -1;
RbS.Checked := false;
RbN.Checked := false;
O seu formulário deverá estar assim:
10
Download