Olá pessoal, neste artigo será demonstrado um conjunto de configurações na propriedade ProviderFlags do componente TSQLQuery que possibilita gerar instruções SQL de Update e Delete para os campos de uma tabela, mesmo quando nossa consulta envolve relacionamento com várias tabelas.
No início parece meio confuso, mas com o decorrer do artigo será visto como esse tipo de funcionalidade pode ser muito útil no cotidiano.
Será utilizado o SGBD MySQL 5.5, Delphi XE e os componentes da paleta DBExpress para acessar os dados, mas nada impede de serem utilizados outros SGBDs, versões anteriores ou posteriores do Delphi ou engines de acesso (ZEOS, ADO etc.), pois essa propriedade ProviderFlags está presente em todas as engines mencionadas.
Para esse artigo vamos construir o seguinte cenário: criar um banco de dados “devmedia” contendo 3 tabelas (“cliente”, “vendedor”, “pedido”).
Tabela para cadastro de clientes
Na tabela de “cliente” vamos criar campos básicos, apenas para ilustração das informações do cliente. Segue o script abaixo:
Listagem 1: Script para criar a tabela de “cliente”
CREATE TABLE `cliente` (
`id` smallint(11) NOT NULL AUTO_INCREMENT,
`nome` varchar(60) DEFAULT NULL,
`fone` char(12) DEFAULT NULL,
`celular` char(12) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Figura 1: Clientes previamente cadastrados
Tabela para cadastro de vendedores
Na tabela de “vendedor” vamos criar apenas dois campos, sendo que o principal é nome do vendedor, segue script abaixo:
Listagem 2: Script para criar a tabela de “vendedor”
CREATE TABLE `vendedor` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nome` varchar(40) DEFAULT NULL,
`comissao` decimal(9,2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Figura 2: Vendedores previamente cadastrados
Tabela para cadastro de pedidos
Na tabela de “pedido” vamos criar alguns campos básicos, somente para ilustração, o detalhe nessa tabela são os campos que fazem relacionamento com as tabelas de “cliente” (campo id_cliente) e “vendedor” (campo id_vendedor). Notem que não vamos gravar dados do cliente como: nome, email, telefone e nem o nome do vendedor, pois essas informações serão capturadas com a instrução SQL. Segue o script abaixo:
Listagem 3: Script para criar a tabela de “pedido”
CREATE TABLE `pedido` (
`id` smallint(11) NOT NULL AUTO_INCREMENT,
`id_cliente` int(11) DEFAULT NULL,
`valor_total` decimal(9,2) DEFAULT NULL,
`data_venda` date DEFAULT NULL,
`id_vendedor` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Observação: Não foram criadas chaves estrangeiras (FK) na tabela “pedido”, o objetivo do artigo não é explanar integridade dos dados, mas sim facilidades que tais configurações podem trazer. Não foi criada uma tabela de “itens_pedido”, os valores na tabela de “pedido” foram cadastrados aleatoriamente.

Figura 3: Pedidos previamente cadastrados
Finalizada a fase de criação da base de dados, vamos abrir o Delphi e criar um novo projeto. Nesse projeto será necessário apenas um formulário, onde será possível visualizar, editar e excluir registros no DBGrid. Para melhor ilustrar o desempenho das configurações na propriedade ProviderFlags, vamos utilizar um componente (TSQLMonitor) da paleta DBExpress, muito interessante para o monitoramento das instruções SQL que são enviadas para o banco de dados.
Vamos inserir no form os seguintes componentes:
Componentes | Configurações das Propriedades |
1 -TSQLConnection | Name = Conexao |
Driver = MySQL | |
Database = devmedia | |
HostName = localhost | |
Password = 011224 //Exemplo | |
ServerCharset = utf8 | |
UserName = root | |
1 - TSQLQuery | Name = “qryPedido” |
SQL = Será descrita abaixo. | |
SQLConnection = Conexao | |
1 - TDataSetProvider | Name = dspPedido |
DataSet = qryPedido | |
UpdateMode = upWhereKeyOnly | |
1 - TClientDataSet | Name = cdsPedido |
ProviderName = dspPedido | |
1 - TDataSource | Name = dtsPedido |
DataSet = cdsPedido | |
1 - TSQLMonitor | Name = SQLMonitor |
SQLConnection = Conexao | |
Active = true | |
1 - TDBGrid | Name = grdPedidos |
DataSource = dtsPedido | |
Align = alTop | |
1 - TMemo | Name = mmoSQL |
ScrollBars = ssVertical | |
Align = alBottom | |
2 - TBitBtn | 1 – Name = btnExcluir |
Caption = “Excluir” | |
Kind = bkCancel | |
1 – Name = btnGravar | |
Caption = “Gravar” | |
Kind = bkOK |
Tabela 1: Lista de componentes e suas respectivas configurações

Figura 4: Layout do formulário
Na tabela acima faltou informar a propriedade SQL do componente TSQLQuery, nessa propriedade temos que digitar nossa instrução SQL para trazer os dados e posteriormente, através do componente ClientDataSet, popular o DBGrid. Essa instrução SQL envolverá dados das três tabelas que criamos acima, mas o grande segredo dessa consulta é que poderemos alterar dados do pedido mesmo trazendo dados de outras tabelas, segue abaixo instrução SQL:
Listagem 4: Instrução SQL para carregar DBGrid
SELECT p.id, c.nome AS cliente, c.email, p.valor_total, p.data_venda, v.nome as vendedor
FROM pedido p INNER JOIN cliente c ON p.id_cliente = c.id
INNER JOIN vendedor v ON p.id_vendedor = v.id
Observem que essa instrução retornará além dos dados da tabela “pedido”, o nome e email do cliente que estão gravados somente na tabela “cliente” e o nome do vendedor que está gravado na tabela “vendedor”, tudo isso é possível através do uso dos campos de relacionamento (id_cliente e id_vendedor) entre as tabelas nas cláusulas do INNER JOIN.
Agora vamos a tão aguardada configuração da propriedade ProviderFlags dos campos. Após inserida a instrução SQL na devida propriedade do componente TSQLQuery, vamos alterar a propriedade Active para true. Com um duplo click ou clicando em cima do componente com o botão direito do mouse e selecionando a opção “Fields Editor...”, será aberta uma janela.

Figura 5: Pop-up com a opção Fields Editor
Após selecionada a opção Fields Editor será aberta uma janela vazia, clicar novamente com o botão direito do mouse dentro dessa janela e selecionar a opção “Add all fields”. Serão adicionados todos os campos da instrução SQL.

Figura 6: Adicionando campos ao Fields Editor
Clicando em cada campo serão exibidas no Object Inspector todas as propriedades do campo, entre elas existe a ProviderFlags, onde temos as seguintes opções:
- pfInUpdate
- pfInWhere
- pfInKey
- pfInHidden

Figura 7: Fields Editor com todos os campos da instrução SQL

Figura 8: Object Inspector com as opções de Flags
Flag | Descrição |
pfInUpdate | Indica se o campo será atualizado |
pfInWhere | Indica se o campo fara parte da cláusula Where |
pfInKey | Indica se o campo é parte da Chave Primária |
pfInHidden | Indica se o campo será oculto para os Clientes |
Tabela 2: Lista de flags e descrição das configurações
Agora vamos iniciar as configurações individuais para cada campo que está no Fields Editor.
Campo | Flag | Valor |
id | pfInUpdate | False |
pfInWhere | True | |
pfInKey | True | |
pfInHidden | False | |
cliente | pfInUpdate | False |
pfInWhere | False | |
pfInKey | False | |
pfInHidden | False | |
pfInUpdate | False | |
pfInWhere | False | |
pfInKey | False | |
pfInHidden | False | |
valor_total | pfInUpdate | True |
pfInWhere | False | |
pfInKey | False | |
pfInHidden | False | |
data_venda | pfInUpdate | True |
pfInWhere | False | |
pfInKey | False | |
pfInHidden | False | |
vendedor | pfInUpdate | False |
pfInWhere | False | |
pfInKey | False | |
pfInHidden | False | |
Tabela 3: Configurações individuais de cada campo
O objetivo desse artigo é demonstrar como atualizar dados de uma tabela envolvida em uma consulta com outras tabelas, usando as configurações do ProviderFlags. Nesse caso vamos alterar e excluir dados da tabela “pedido”, sem alterar nenhuma informação das tabelas “cliente” e “vendedor” apesar das duas estarem envolvidas na instrução SQL de consulta.
Campo “id” é Chave Primária da tabela “pedido” então informamos que ele é o campo chave primária e que participará da cláusula Where das instruções.
Como os campos “cliente” e “email” não fazem parte da tabela “pedido”, deixamos todas as flags como false, isso indica que esses campos não fazem parte da Chave Primária, não serão atualizados e não participarão da cláusula Where. Aí está o segredo para trabalharmos com várias tabelas e manipularmos dados de apenas uma única tabela, pois essas configurações isolam esses dois campos do restante das instruções. Poderemos observar melhor com as informações do SQLMonitor.
Campos “valor_total” e “data_venda” pertencem à tabela “pedido”, então nesse caso poderão ser atualizados com a instrução Update. Para isso deixamos como True apenas a flag pfInUpdate, pois não fazem parte da Chave Primária e não existe necessidade dos mesmos fazerem parte da cláusula Where.
Campo “vendedor” não faz parte da tabela “pedido” somente da tabela “vendedor”, então todas as suas flags serão alteradas para False, pois ele não é parte de Chave Primária, não será atualizado e não participará das cláusulas Where.
Agora vamos codificar os dois botões, serão códigos bem simples, pois vamos alterar e excluir os dados direto no DBGrid.
O botão “Gravar” verifica se cdsPedido está em estado de Edição ou Inserção, caso verdadeiro, grava e atualiza as informações no banco de dados.
Listagem 5: Código do evento OnClick do botão “btnGravar”
if cdsPedido.State in [dsEdit, dsInsert] then
begin
cdsPedido.Post;
cdsPedido.ApplyUpdates(0);
end;
O botão “Excluir” verifica se cdsPedido está em estado de Edição ou Inserção, caso verdadeiro, exclui e atualiza informações no banco de dados.
Listagem 6: Código do evento OnClick do botão “btnExcluir”
if cdsPedido.State in [dsBrowse] then
begin
cdsPedido.Delete;
cdsPedido.ApplyUpdates(0);
end;
Para finalizar, vamos exibir as instruções SQL que estão sendo enviadas para o banco de dados utilizando o componente TSQLMonitor.
No evento OnLogTrace do componente TSQLMonitor vamos definir que todas as instruções que forem enviadas para banco de dados serão exibidas no componente TMemo, desse modo poderemos observar toda a “mágica” das configurações do ProvideFlags.
Listagem 7: Código do evento OnLogTrace do componente TSQLMonitor
mmoSQL.Lines.Add(TraceInfo.Message);

Figura 9: Informações transmitidas ao banco de dados
Pronto, agora é só executar aplicação, como já foram cadastradas informações para testes segue abaixo demonstração.
Observem que ao iniciar a aplicação e carregar o DBGrid já foram transmitidas informações de consulta para o banco de dados.
Vamos alterar o valor_total da venda “10” para 2000,00 e clicar no botão “Gravar”, observem a instrução SQL usando na cláusula Where o valor do campo “id”, somente a tabela “pedido” será modificada.

Figura 10: Instrução SQL para Update do registro
Agora vamos selecionar a venda “7” e clicar no botão “Excluir”, será excluído o registro da tabela “pedido” usando o valor do campo id na cláusula Where.

Figura 11: Instrução SQL para Exclusão do registro
Observem que a tabela “pedido” só possui os ids do cliente e do vendedor, os restantes das informações como nome e email estão gravadas nas respectivas tabelas. Para capturar todas essas informações em uma mesma consulta usamos JOINs, ou seja, comparações entre as tabelas. Mas existe a necessidade de alterar informações dos campos da tabela “pedido”, então foram configuradas adequadamente as flags isolando os campos que não fazem parte dessa tabela. Com essa técnica foi possível editar e excluir registros da tabela “pedido” sem alterar nenhuma informação das outras tabelas relacionadas na consulta.
Bom pessoal, nesse artigo foi demonstrado como podemos configurar a propriedade ProviderFlags para trabalhar de acordo com nossas necessidades, existem várias outras combinações possíveis. Com o auxílio do SQLMonitor foi possível observar como as instruções SQL são enviadas para o banco de dados.
Espero que tenham apreciado e até a próxima.
Caso surja alguma dúvida meu e-mail é wllfl@ig.com.br. Fiquem à vontade também para usar a seção de comentários.
Abraço a todos!