No último artigo sobre Query no Delphi, eu prometi que publicaria um novo artigo abordando a passagem de parâmetros utilizando Query, não é? Bom, e como promessa é dÃvida, o melhor é pagar antes que me cobrem, haha.
Pessoal, esse artigo trata da criação e preenchimento de parâmetros em uma SQL de forma dinâmica, evitando fixar valores em tempo de projeto. Confira!
Introdução
A passagem de parâmetros em uma Query é bastante útil quando é necessário atribuir valores previamente desconhecidos em um comando SQL. Em outras palavras, ao invés de criar uma SQL com valores fixos, realizamos um preenchimento dinâmico desses valores em tempo de execução do aplicativo.
Para inÃcio de nossos exemplos, considere a seguinte SQL:
1 |
Select * from CLIENTES where Nome = 'Andre Celestino' |
É um comando de seleção simples, apenas para obter os dados do cliente que possua o nome “Andre Celestino”. Observe que essa SQL pode ser atribuÃda normalmente a uma Query da seguinte forma:
1 2 3 |
Query1.SQL.Clear; Query1.SQL.Add('Select * from CLIENTES where Nome = ''Andre Celestino'''); Query1.Open; |
Ao abrir a Query, os dados do cliente “Andre Celestino” serão retornados para a aplicação, ok? No entanto, a nossa Query SEMPRE irá trazer esse único registro, já que a aplicação foi compilada com o valor fixo na SQL e não há como modificá-lo. Então temos um problema: e se o usuário quiser visualizar os dados de outro cliente?
Já sei! Basta trocar o nome no código-fonte, compilar e gerar outro executável, não é?
Não, nem pense nisso! A solução é configurar a Query para receber o valor que o usuário digitar. Considere que adicionamos um campo na tela chamado edtNome do tipo TEdit
, para que o usuário possa digitar o nome do cliente no qual deseja visualizar os dados. Ao invés de manter o valor fixo, vamos modificar o código para receber o valor do campo de texto:
1 2 3 |
Query1.SQL.Clear; Query1.SQL.Add('Select * from CLIENTES where Nome = ''' + edtNome.Text + ''''); Query1.Open; |
Caramba, quantas aspas! É necessário tudo isso?
Sim. O nome do cliente é uma string (tipo texto), e precisa ser envolvido em aspas para que o banco de dados consiga interpretar o valor. Agora, imagine que surja a necessidade de filtrar os dados por mais dois campos do tipo texto: “Endereço” e “Cidade”. Bom, tenho certeza que você pensou na quantidade de aspas, certo? Pois é, isso realmente pode dificultar a escrita do código, além de deixar o código-fonte um tanto quanto confuso.
Eis que lhes apresento uma forma bem mais fácil de preencher uma SQL dinamicamente: através de parâmetros.
Parâmetros na Query
Aaaah, até que enfim! Mas como funciona?
Simples, vamos alterar o código mais uma vez:
1 2 3 4 |
Query1.SQL.Clear; Query1.SQL.Add('Select * from CLIENTES where Nome = :pNome'); Query1.ParamByName('pNome').AsString := edtNome.Text; Query1.Open; |
Nossa, não entendi nada!
Ok, vamos lá. Para criar um parâmetro dentro de uma Query, basta escrever o nome seguido de dois pontos (:), sem espaços conforme o exemplo acima, onde o nome do parâmetro criado é pNome
. Isso significa que essa “parte” da SQL será substituÃda por algum valor em tempo de execução. Em seguida, após declarar o parâmetro, é necessário preenchê-lo utilizando o método ParamByName
, que, neste caso, é o conteúdo digitado no campo edtNome
.
Pronto! Ao rodar a aplicação, a Query irá retornar os dados do cliente cujo nome foi digitado no componente edtNome
!
Só temos mais um probleminha: o registro será encontrado somente se o usuário digitar o nome completo do cliente. Isso é bem inviável, não? Para resolvermos isso, basta realizar uma busca parcial do registro, utilizando a cláusula LIKE na SQL e adicionando o sÃmbolo de porcentagem ao nome:
1 2 3 4 |
Query1.SQL.Clear; Query1.SQL.Add('Select * from CLIENTES where Nome like :pNome'); Query1.ParamByName('pNome').AsString := edtNome.Text + '%'; Query1.Open; |
O sÃmbolo de porcentagem, a grosso modo, permite que o banco de dados selecione todos os registros que contenham parcialmente o nome digitado pelo usuário. Sendo assim, se o usuário digitar somente “Cele”, o cliente “Andre Celestino” será encontrado.
Repare que eu utilizei o comando AsString
para atribuir o valor. Este comando indica que o conteúdo que será atribuÃdo ao parâmetro é do tipo string, ou seja, um texto. Se estivéssemos realizando uma busca pelo código do cliente (considerando que o código é do tipo inteiro), então trocarÃamos o comando para AsInteger
:
1 2 3 4 |
Query1.SQL.Clear; Query1.SQL.Add('Select * from CLIENTES where Codigo = :pCodigo'); Query1.ParamByName('pCodigo').AsInteger := StrToInt(edtCodigo.Text); Query1.Open; |
Há também outras opções para atribuição de valores, como datas (AsDateTime
) e valores decimais (AsFloat
).
Inserindo dados com parâmetros
Da mesma forma que criamos parâmetros em uma instrução SELECT, eles também podem ser criados em instruções INSERT, UPDATE ou DELETE. Para exemplificar, confira o exemplo de uma inserção utilizando parâmetros:
1 2 3 4 5 6 7 8 9 10 |
Query1.SQL.Clear; Query1.SQL.Add('Insert into CLIENTES'); Query1.SQL.Add('(Codigo, Nome, DataNascimento)'); Query1.SQL.Add('values (:pCodigo, :pNome, :pDataNascimento)'); Query1.ParamByName('pCodigo').AsInteger := StrToInt(edtCodigo.Text); Query1.ParamByName('pNome').AsString := edtNome.Text; Query1.ParamByName('pDataNascimento').AsDateTime := StrToDate(edtData.Text); Query1.ExecSQL; |
Simples, não?
Só pra complementar, veja que utilizei o comando Add
para concatenar a instrução SQL em linhas, principalmente para evitar a necessidade de utilizar o operador “+”.
Pessoal, espero que esse artigo tenha sido útil! Os exemplos contidos nesse artigo podem ser baixados neste link, desenvolvidos em Delphi 7. Para que você possa abri-los, é necessário ter o Firebird instalado no computador, ok?
Se você baixar o exemplo, observe que utilizei um TClientDataSet
para manter os registros em memória. Em um futuro não tão distante, também publicarei um artigo sobre utilização da Query como fonte de dados.
Grande abraço e até mais!
Muito bom em batera, aproveitando a deixa, em um proximo artigo seu sobre query, fale sobre query em tempo de execução, ajuda muito, forte abraço.
Opa Ivan, sugestão anotada!
Valeu, garoto! Abraço!
CARO ANDRE, TRABALHO COM DELPHI 6 COM INTERBASE. PRECISO SELECIONAR TODOS OS REGISTROS DA TABELA, MENOS OS REGISTROS QUE TENHAM O CODIGO = ‘TDE’. OS OUTROS CODIGOS PODEM APARECER. COMO EU FAÇO? TENTEI CODIGO ‘TDE’ E NÃO CONSEGUI.
OBRIGADO, DESDE JA.
Olá, Jimmy! Basicamente, bastaria utilizar a seguinte instrução SQL em uma Query:
Select * from TABELA where Codigo <> 'TDE'
Mesmo assim, podemos conversar por e-mail para que eu possa compreender melhor o problema!
Lembrando que o usuário pode substitui os parâmetros: ASSTRING, ASINTEGER, ASFLOAT, ASDATETIME por apenas um VALUE… só não sei se o ASDATETIME será eficiente, hehe, mas geralmente dá certo.
Abraço..hehe
Isso aÃ, Adriano! Na verdade, as funções AsString, AsInteger, etc, são úteis para manter compatibilidade com o tipo de dados. Obrigado pelo comentário!
Boa tarde Adré!
Tenho o delphi 2010 e não estou conseguindo atualizar os dados com está sintaxe, onde estou errando. Desde já agradeço.
with Module.zQNivers do
Begin
Module.zQNivers.Close;
Module.zQNivers.SQL.Clear;
Module.zQNivers.SQL.ADD (‘ Update Nivers’);
Module.zQNivers.SQL.ADD (‘ SET (A_Nome,B_Niver)’);
Module.zQNivers.SQL.ADD (‘ WHERE A_Nome =:PNome’);
Module.zQNivers.SQL.ADD (‘ AND B_Niver =:PData’);
Module.zQNivers.ParamByName(‘PNome’).AsString:=ed_Nome.Text;
Module.zQNivers.ParamByName(‘PData’).AsDateTime:=StrToDateTime(ed_Data.Text);
Module.zQNivers.Prepare;
Module.zQNivers.ApplyUpdates;
Module.zQNivers.ExecSQL;
end;
Abraço:
Sinval
Olá, Sinval! Aparentemente, o erro está na instrução Update SQL. Vou entrar em contato por e-mail para te ajudar melhor, ok? Abraço!
Bom dia Andre.
Mas neste caso faltou preencher o SQL Editor para criar o parametro, ou não é necessario.
No aguardo,
Bom dia, Cristiano. Neste caso, como estamos criando o parâmetro em tempo de execução (com os dois pontos), não é necessário preencher o SQL Editor. A própria Query irá identificar os parâmetros e aguardar os valores esperados. Abraço!
Andre, boa noite. Otimo site por sinal e sempre ajudando quem necessita de ajuda. Parabens.
Tenho algumas duvidas.
Gostaria de fazer consulta tanto com a DESCRIÇAO como pelo ARTIGO com apenas um edit, no evento onchange, sem precisar de um botao.
Tipo eu digitando e aparece no meu grid, exemplo CAN, e no meu cadastro aparecendo ANDRE, FERNANDO, ETC. Ou por codigo tipo digito 32, e me aparece no grid 5321, 9832, etc. Consegui fazer um ou outro funcionar, mas não os dois. onde pode estar o erro? Eu tenho Adoquery chamado (Qprodutos) um datasource chamado (dsqprodutos). Minha tabela chama-se Produtos. Meus campos de artigo se chama (CADP_ARTIGOPROD) e da descriçao do produtos chama-se (CADP_DESCRPROD).Se puder nos ajudar, ficaremos gratos. Abraço, Cristiano
Olá, Cristiano. Realizar uma consulta por dois campos ao mesmo tempo pode ser feito tanto pela instrução SQL quanto pela propriedade Filter. Para esclarecer melhor, entrarei em contato por e-mail. Obrigado!
Alguma forma de ver o conteúdo de Module.zQNivers.SQL.
tentei fazer e retorna erro : HWND e Tstring incompatÃveis….
Olá, Emerson. Você pretende ver o conteúdo da propriedade SQL com os parâmetros preenchidos? Se este for o caso, é possÃvel apenas com uma função especÃfica implementada manualmente.
Boa tarde André,
Estou desenvolvendo uma aplicação pequena mas estou com problemas numa select, seguinte: Tenho duas tabelas Venda e ItensVenda, a primeira tem uma PK(Comanda) e a segunda uma FK(codigo) que faz referencia a PK da primeira. Queria selecionar “N” Campos (Ex: CodProd, Produto, ValUnit, ValTot, etc) da tablela ItensVenda, onde o Codigo (da tabela ItensVenda) fosse igual a Comanda (da tabela Venda).
Fico na expectativa da ajuda e desde já, agradeço a a sua atenção.
Olá, Fábio! Obrigado por deixar o comentário!
Essa situação que você mencionou é bastante comum no desenvolvimento de software, e uma das alternativas é utilizar parametrização com Queries.
Para ficar mais fácil, vou entrar em contato por e-mail, ok?
Abraço!
Há poucos que disponibilizam informação de uma forma simples sem complicação e com humildade, pois geralmente vejo pessoas que querem mostrar que sabem muito e acabam colocando varias linhas sem necessidade e confundindo o leitor.
parabéns e obrigado.
Obrigado pelo comentário e pela motivação, Ribamar! Fico contente que tenha encontrado o blog e gostado do artigo.
Um grande abraço!
Olá, com certeza vc já deve saber, mais eu achei bem interessante e se vc quiser implementar, sobre a consulta com LIKE, ele diferencia Maiúscula de minúsculo, um jeito de burlar isso é:
Query.SQL.Clear;
Query.SQL.Text := ‘select * from Produtos where upper(descricao) like :descricao’;
Query.ParamByName(‘descricao’).AsString := AnsiUpperCase(‘%’ + EditConsulta.Text + ‘%’);
Query.Open;
Nesse caso eu usei um datasource para usar o dbgrid.
Será que tem outro jeito de não diferenciar maiúsculo de minúscula.
E será que tem como mostrar uma lista dos produtos sem usar o datasource.
Olá, Ribamar! Tem razão, quando se usa o LIKE há essa questão da diferença entre maiúsculo e minúsculo. Eu conheço 3 formas para fazer o tratamento:
– No banco de dados: utilizar o UPPER na SQL
– Na aplicação: Utilizar o AnsiUpperCase (assim como você sugeriu)
– Ajustar a propriedade CharCase da TEdit para ecUpperCase.
A respeito do DataSource, se você estiver utilizando um TDBGrid, a utilização de um DataSource é obrigatória, já que o TDBGrid precisa deste componente para buscar os dados que serão exibidos para o usuário. Caso você não pretenda utilizar um DataSource, basta usar componentes que não sejam DB-Aware, como o TStringGrid.
Obrigado pelo comentário!
Ola gostaria de resolver esse problema uso compontente zeos e firebird 2,5, sempre da um erro tem que resetar a aplicaçà o porem insere o codigo apenas ele.
dmsgc.zqclientes.SQL.Clear;
dmsgc.zqclientes.SQL.Add(‘Insert into clientedb’);
dmsgc.zqclientes.SQL.Add(‘(codigoclie, rgclie)’);
dmsgc.zqclientes.SQL.Add(‘values (:pCodigoclie, :prgclie)’);
dmsgc.zqclientes.ParamByName(‘pCodigoclie’).AsInteger:= StrToInt(dbedit1.Text);
dmsgc.zqclientes.ParamByName(‘pRgclie’).AsString:=dbedit2.Text;
dmsgc.zqclientes.ExecSQL;
Olá, Adriano! Aparentemente o seu código está correto. De qualquer forma, entrarei em contato com você por e-mail, ok?
Abraço!
Olá André, primeiro parabéns pelo site tem sido de grande ajuda. Estou com a seguinte dificuldade:
Usando select * from tabela where in(1,2,3) direto no firebird obtenho o resultado da consulta sem problema, porém, quando vou usar em tempo de execução utilizando um TSimpleDataSet dá erro quando passo mais de um valor. Já coloquei pra passar os valores por string, integer e nada. Pergunto, é possÃvel usar a clásula IN em tempo de execução no delphi e sim como faço? Desde já agradeço a a ajuda.
Olá, Júnior. É possÃvel utilizar a cláusula IN em tempo de execução, sim. Vou entrar em contato com você por e-mail para pedir mais detalhes, ok?
Abraço!
André, obrigado pela ajuda. Sua orientação para a questão acima foi excelente, o código está funcionando perfeitamente. Agora tenho outro problema com relação ao assunto com uso de mais de uma tabela na consulta utilizando apelidos na tabela e fazendo a junção através de INNER JOIN. Dá erro de coluna desconhecida. Veja o código:
Dmr.slqFichaMembro.SQL.Add(‘SELECT M.NOMEMEMBRO, M.IDMEMBRO, C.DESCRICAOCARGO FROM MEMBRO M’ +
‘INNER JOIN CARGO C ON M.CARGO_IDCARGO = C.IDCARGO’ +
‘WHERE M.IDMEMBRO IN’ + Parametros);
Erro
—————————
Debugger Exception Notification
—————————
Project iebm.exe raised exception class TDBXError with message ‘Token unknown – line 1, column 120
—————————
O erro aparece no campo informado na clásula WHERE. Não conseguir identificar aonde está o erro.
Olá, Junior. Aparentemente há um erro de sintaxe na sua instrução SQL. Vou entrar em contato com você novamente, ok? Abraço.
Olá André, conheci o site agora e já gostei! Ótimo artigo, obrigada por compartilhar seu conhecimento de forma clara e descontraÃda 🙂
Olá, Ammy! Fico contente que o tenha gostado do artigo! Obrigado pelo feedback!
Boa noite André, Conheci seu site recentemente, e vejo que você tem um grande conhecimento. Desenvolvi uma aplicação muito tempo atrás em Delphi 5 e me pediram para fazer uma mudança na aplicação. Só que precisaria criar uma nova tabela e fazer algumas alterações em uma tabela existente. Usei o Dbisam. Como criar e fazer alteração via código?
Olá, Wilson. Já passei por uma situação semelhante e criei um atualizador automático, ou seja, um aplicativo separado que se conecta ao banco de dados e realiza as alterações necessárias na(s) tabela(s). Após um tempo, modifiquei este aplicativo para que ele carregasse um script SQL em tempo de execução, me dispensando de gerar um novo executável para cada atualização no banco de dados do cliente.
Obrigado por deixar o comentário. Abraço!
Caro André, Parabéns pela iniciativa!
Minha dúvida é como escrever uma query e montá-la em tempo de execução, de acordo com a utilização ou não de um parâmetro.
Tipo. Numa consulta eu tenho diversos campos para filtro, mas os parâmetros serão utilizados de acordo com o tipo de consulta que o usuário desejará fazer.
O intuito é usá-la num programa de estatÃstica.
Ex. Numa comunidade tal, quantos homens com idade entre 20 e 45 anos, moram em casa de alvenaria, ganham entre 800 e 2000 reais e possuem 03 dependentes.
Deu pra entender?
Olá, David. Entendi perfeitamente, e inclusive já me deparei com situações semelhantes. Vou lhe enviar um e-mail solicitando mais detalhes, ok?
Abraço!
Caro André, Parabéns pela iniciativa!
Minha dúvida é como escrever uma query e montá-la em tempo de execução, de acordo com a utilização ou não de um parâmetro.
Tipo. Numa consulta eu tenho diversos campos para filtro, mas os parâmetros serão utilizados de acordo com o tipo de consulta que o usuário desejará fazer.
O intuito é usá-la num programa de estatÃstica.
Ex. Numa comunidade tal, quantos homens com idade entre 20 e 45 anos, moram em casa de alvenaria, ganham entre 800 e 2000 reais e possuem 03 dependentes.
Deu pra entender?
Opa, Adalto, obrigado!
Certo, vamos lá.
Você pode criar a Query em tempo de execução e atribuir os filtros conform os critérios da consulta. No exemplo abaixo, utilizo um componente TSQLQuery para montar a instrução e um componente TRadioGroup simulando a escolha do usuário:
Olá,
Estou fazendo uma aplicação em lazarus para rodar no wince, nesta aplicação eu tenho que fazer um conexão com o Postgres e SqlServer, eu já consegui fazer a busca no banco, agora eu queria saber como eu faço para transforma os resultados que eu obtive, em objetos.
Olá, Lucas, tudo bem? Infelizmente não tenho conhecimentos aprofundados em Lazarus e WinCE, portanto não posso te ajudar melhor.
Mesmo assim, não deixe de participar do fórum do Lazarus neste link:
http://www.freepascal.com.br/
Certamente eles poderão te dar uma força! Abraço!
Olá André, estou com um problema na minha aplicação,tenho um sistema que marca o horário que o funcionário sai para o almoço e registra a hora prevista para o seu retorno. Estou tentando fazer com que o sistema avise ao operador, no momento que a hora prevista for ultrapassada, usando a hora atual do computador. Gostaria de uma orientação sua ou um código SQL ou vice-versa para resolver esse problema. Fico grato desde já, pela a sua atenção.
Olá, Antonio! Vou entrar em contato com você para pedir mais detalhes, ok?
Abraço!
A ideia atual que mim veio agora,era usar um despertador feito em delphi. Agora só, tenho que fazer com que esse despertador, verifique os registros(ou no banco de dados ou dbgrid)para avisar os funcionários que passaram do horário do almoço. Qualquer duvida sobre o meu projeto pode entrar em contato.
Olá André boa noite, tenho lido suas publicações que por sinal são ótimas.
Porém tenho quebrado um pouco a cabeça em um projeto que estou fazendo em Delphi 5 com banco de dados no Mysql. E eu quero acessar o banco usando os componentes: Database, Query e DataSource (é uma das exigências do projeto) dentro de um DataModule.
Queria saber se você pode me ajudar criando um exemplo pratico de como Inserir, Consultar, Deletar e Alterar os registros no banco…
Demais deixo um abraço ao amigo, pois suas publicações tem acrescentado muito conhecimento na minha vida.
Boa noite, Jonas. Vou lhe enviar alguams dicas por e-mail, ok? Abraço!
Olá André, gostei muito da publicação e me acrescentou muito. Estou com um problema e talvez você possa me auxiliar. Estou construindo um sistema em Lazarus, mas acredito que em Delphi, que também gosto muito, tenha o mesmo problema. Faço uma consulta utilizando o componente ReadOnlyQuery e TZquery, que retorna um campo do tipo texto muito extenso. Na consulta sql do pgAdmin retorna completa, mas no sistema tanto no relatório quanto em um grid ou dbgrid não retorna todos os dados, a consulta vem incompleta. A consulta retorna até um ponto. Acredito que seja alguma configuração nos objetos. Você já teve algo parecido?
Grata, LÃlian.
Olá, Lilian!
Ainda não tive a oportunidade de trabalhar com o Lazarus ou com o PostgreSQL no Delphi, mas acredito que este problema esteja relacionado à configuração das propriedades da Query que faz a consulta. Para ficar mais fácil, vou pedir mais alguns detalhes por e-mail, ok?
Abraço!
Bom dia!
Estou com um grande problema e preciso de ajuda.
Estou criando uma aplicação onde Faço uma pesquisa com o componente IBQuery e preciso alterar os dados dessa pesquisa com isso usei o IBQuery + IBUpdateSql. Consegui configurar os dois, porém na hora de salvar esta dando erro. Alguém sabe como funciona esses componentes?
Olá, Marcelo! Se possÃvel, poste a mensagem de erro para que possamos ajudá-lo!
Abraço!
Boa tarde sou iniciante ainda em delphi.
preciso fazer um consulta com parametros em dois registros. e depois verificar se eles existem. mas não estou conseguindo.
//*****************************************************************************
with DM_VENDAS.CDS_PEGA_MESA do
begin
close;
FetchParams;
Params.ParamByName(‘MESA’).AsInteger:= 2;
Params.ParamByName(‘STATUS’).AsString:=’CONSUMINDO’;
Open
end;
//*****************************************************************************
if (dm_vendas.CDS_PEGA_MESA.Params.ParamByName(‘MESA’).AsInteger = 2) and (dm_vendas.CDS_PEGA_MESA.Params.ParamByName(‘STATUS’).AsString = ‘CONSUMINDO’) then
begin
ShowMessage(‘Mesa já Cadastrada’);
end;
se mudar o status da mesa, continua a dizer que a mesa ja existe.
alguem poderia me ajudar por favor?
Olá, Sérgio! Ao meu ver, há um equÃvoco no código: na comparação IF, deve-se utilizar o FieldByName, e não o ParamByName, lembrando que o ParamByName só é utilizado para injetar valores em uma instrução SQL, portanto, não deve ser utilizado em comparações.
Abraço!
Ola Andre.
A dica eh muito boa porem sempre que uso esta tecnica recebo esta mensagem:
Preparing statement: select * from PRODUTO
where codprod = :consulta
Error: *** IBPP::SQLException ***
Context: Statement::Prepare( select * from PRODUTO
where codprod = :consulta )
Message: isc_dsql_prepare failed
SQL Message : -206
Column does not belong to referenced table
Engine Code : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -206
Column unknown
CONSULTA
At line 2, column 22
Alguma ideia por que recebo esta mensagem?
Olá, Narley!
Como você está preenchendo o parâmetro? Apenas para frisar, o valor do parâmetro deve ser atribuÃdo utilizando o ParamByName, ok?
Abraço!
Estou tentando fazer um relatório de caixa onde apareça as vendas e os recebimentos por periodo..no relatório no Report Build está OK o problema é os parametros no Delphi…o aparece as vendas no relatório se tiver recebimento e eu não quero assim! eu quero que traga vendas se tiver e se não tiver traga os recebimentos..meu codigo está assim:
with DM.SQL_caixa do
begin
Close;
SQL.Clear;
SQL.Add(‘SELECT * FROM VIEW_PEDIDOS’);
SQL.Add(‘WHERE DATA BETWEEN :Data_inicial AND :Data_final’);
SQL.Add(‘AND entrasaldo = “S”‘);
ParamByName(‘Data_inicial’).Value := FormatDateTime(‘yyy-mm-dd’, data_inicial.Date);
ParamByName(‘Data_final’).Value := FormatDateTime(‘yyy-mm-dd’, data_final.Date);
Open;
with DM.SQL_Recebimento do
begin
Close;
SQL.Clear;
SQL.Add(‘SELECT * FROM parcelas_prontas’);
SQL.Add(‘WHERE carne_data_pago BETWEEN :Data_inicial AND :Data_final’);
SQL.Add(‘AND carne_status = “SIM”‘);
ParamByName(‘Data_inicial’).Value := FormatDateTime(‘yyy-mm-dd’, data_inicial.Date);
ParamByName(‘Data_final’).Value := FormatDateTime(‘yyy-mm-dd’, data_final.Date);
Open;
if RecordCount > 0 then
begin
DM.RPB_caixa.PrintReport;
end
else
begin
if Application.MessageBox(‘Não existe venda ou recebimento nesse periodo’,’Sistema de Vendas – SYSPDV’, MB_OK) = IDOK then
end;
end;
end;
como faço pra buscar os registro das 2 query?
Olá, Jhonlenon, tudo certo?
Ao que me parece, a solução para o seu caso é utilizar o comando UNION na instrução SQL. Esse comando faz a união de duas consultas separadas, resultando em um conjunto único de registros. Na prática, seria algo como:
Select * from VIEW_PEDIDOS ...
UNION
Select * from parcelas_prontas
Para ajudá-lo melhor, confira os artigos abaixo do 1KeyData e do Macoratti:
http://www.1keydata.com/pt/sql/sql-union.php/
http://www.macoratti.net/13/05/sql_uni1.htm
Olá Boa tarde André Luiz…agradeço pela ajuda no tópico…realmente UNION foi a melhor solução…estou fazendo outro relatório interno de lançamentos Manual de credito e debito…estou querendo obter o saldo (CREDITO – DEBITO) = Saldo
tenho uma Tabela chamada lancamentos, com os seguintes campo:
CREATE TABLE servidormysql.lancamentos (
id INT(11) NOT NULL AUTO_INCREMENT,
descricao VARCHAR(200) DEFAULT NULL,
data DATE DEFAULT NULL,
valor DOUBLE DEFAULT 0,
tipo CHAR(10) DEFAULT NULL,
PRIMARY KEY (id)
)
ENGINE = INNODB
AUTO_INCREMENT = 18
AVG_ROW_LENGTH = 8192
CHARACTER SET latin1
COLLATE latin1_swedish_ci;
Adicionei um TDBRadiogroup no formulario de inseri ai marco Debito ou Credito…como se trata de um relatório interno usando Report Build preciso fazer isso em campo calculado! onde me traga o saldo…também não estou conseguindo gravar o valor debito negativo no banco de dados…
Uso o banco de dados Mysql e Delphi 2010
Peço ajuda André…..
Olá, Jhonlenon.
Assim que possÃvel, vou entrar em contato com você, ok?
Abraço!
Tudo bem André..Eu aguardo
Olá andré…..estou com um problema aqui…tenho uma view_pedidos que eu uso para trazer os itens do pedido da venda, no relatório..porém ele duplica os valores total do pedido quando tenho mais de um item na venda..isso é normal, por exemplo tenho uma venda com o numero do pedido 000654 ai tenho 4 itens
a view traz assim
Pedido Item QTD Valor Unidade ValorPedido
000654 01 02 50,00 250,00
000654 03 01 60,00 250,00
000654 05 03 30,00 250,00
Eu não posso agrupar pelo o numero do pedido…porque preciso de todos o itens no pedido com seus valores
fiz com DISTINCT mais não deu certo no Report Build..ele não obedece o DISTINCT que coloco dentro da propriedade calculo
Select sum(DISTINCT(valorpedido)) from view_pedidos where data BETWEEN ‘2015-01-01’ and ‘2015-01-01’
tenho que somar o valorpedido sem repetir os valores
Olá, Jhonlenon!
Em breve entrarei em contato! Abraço!
Olá, André… realmente tive que criar outra view trazendo os valores total com desconto. A view pedidos ficou só para trazer os itens mesmo.
Obrigado… até a próxima.
Certo, Jhonlenon! Essa realmente parecia ser a melhor solução!
Abraço!
Olá André…tenho esse escript que uso no SQL Server….mais estou desenvolvendo um sistema em Delphi e Mysql…esse select é pra trazer os banco de dados….mais não sei como fazer no Mysql…no SQL Server é esse aqui
Select name
From Master.sys.Databases
Where name Not In (‘Distribution’,’Master’,’model’,’msdb’,’tempdb’,’ReportServer’,’ReportServerTempDB’)
como converter esse script para o Mysql?
Cara você não sabe como esse post me ajudou!!! Muito obrigado mesmo e fica com Deus!!!
Olá, Ramon!
Rapaz, comentários como o seu me deixam bastante contente!
Obrigado!
Rapaz, seu post é excelente e também me ajudou muito.
gostaria de um exemplo simples para iniciante mesmo, de um comando Sql que busque mais parâmetros tipo nome, endereço , data de nascimento.só pra eu ter uma base mesmo e entender.Um código Sql que busque com select mais de um parâmetro.
obrigado e parabéns
Olá, Gilmar, tudo bem?
Primeiramente, gostaria de agradecê-lo pelo comentário e também pelo feedback sobre o artigo!
Gilmar, não conheço o seu nÃvel de conhecimento em programação, então eu acho mais fácil você iniciar as atividades de codificação e, à medida que surgir as dificuldades, você entra em contato para eu possa orientá-lo, pode ser?
Abraço!
Claro André, obrigado pela atenção.
De imediato este seu exemplo abaixo me ajudou muito:
Query1.SQL.Clear;
Query1.SQL.Add(‘Select * from CLIENTES where Codigo = :pCodigo’);
Query1.ParamByName(‘pCodigo’).AsInteger := StrToInt(edtCodigo.Text);
Query1.Open;
ele faz uma busca na tabela clientes onde o campo Código é passado pelo usuário no edtCodigo.text.O que preciso é acrescentar mais um campo na busca, onde o usuário digitaria por exemplo o Código no campo edtCodigo e datacadastro no campo edtDatacadastro.
De inicico este codigo já me ajudaria muito.
Atenciosamente,
Oi, Gilmar!
Certo, vou lhe enviar um exemplo por e-mail de como ficaria o código de uma Query para selecionar campos de diferentes tipos de dados, ok?
Abraço!
Ola, na verdade o que eu preciso é atraves de um select preencher um combobox, mas apenas com valores e sim apenas com os campos, ex: select nome, email, fone from pessoas
no combo:
nome
email
fone
Abracos
Olá, Anderson. Pelo que entendi, você precisa exibir a estrutura de uma tabela no ComboBox, e não os dados, correto?
Bom, neste caso, a sua instrução Select será um pouco diferente. Procure por “select field names from table” no Google, acompanhado do nome do banco de dados que você está utilizando. Cada banco de dados possui uma forma diferente de retornar essas informações.
Boa sorte. Abraço!
Muito bom seu post!
meu velho como faz para gerar ID automatico sequencial nessa query?
estou tentando dessa forma mas retorna a mensagem: cannot perform this operation on a closed dataset.
abaixo o que estou tentando…
Dar uma forcinha ae meu velho! vlw obrigado
Olá, Carlos, tudo bem?
Pelo que sei, você não pode chamar um Refresh em um DataSet fechado. Provavelmente este é o erro do seu código.
Abraço!
eu removi o SqlImoveis.Refresh; mas mesmo assim aparece mensagem: cannot perform this operation on a closed dataset. alguma sugestao de como resolver ? vlw abraço !
Carlos, acredito que o comando “First” também não é permitido quando o DataSet está fechado.
Revise o seu código e remova todos os comandos de acesso aos dados do DataSet quando ele estiver fechado, ok?
Abraço!
ja fiz varias coisas e nada resolvido, no caso que quero é gerar ID automatico.
tem algum exemplo ?
Carlos, você pode usar o MAX na instrução SQL para obter o maior número e somar + 1:
Porém, não sou de acordo com esse tipo de solução. Isso causaria erros de integridade em aplicações Cliente/Servidor.
Sugiro que o ID seja atribuÃdo imediatamente antes de salvar o registro, por exemplo, através de uma Trigger no banco de dados.
Abraço.
boa tarde meu nome é cleber estou precisando uma busca parcial do registro,utilizei esse codigo
” utilizando a cláusula LIKE na SQL e adicionando o sÃmbolo de porcentagem ao nome:”
ele funciona porem ele so pega o comeco do nome preciso que ele faça uma pesqusa tanto pelo começo , como no final ex
cod
7135-573
digitando 7135-
digitando -573
que me retorne 7135-573
Olá, Cleber, tudo bem?
Para pesquisar pelo conteúdo parcial, é necessário adicionar um sinal de porcentagem no inÃcio também, ficando dessa forma:
Espero que lhe ajude!
Abraço!
Boa noite.
Estou fazendo um projeto no delphi e estou criando o codigo automatico pela Query onde o meu professor achou melhor. mas estou tendo alguns erros sera que pode me dar uma opinia: na query eu tenho o seguinte codigo: select max(CLI_COD) as Maior
from CLIENTE
e no formulario:
mas estou tendo erro.
Boa noite, Larissa, tudo bem?
O método “Add” da Query não tem um retorno. É uma procedure para atribuir uma instrução SQL dentro da Query, portanto, não é possÃvel receber o valor da forma como você codificou.
Primeiro, você precisa executar essa SQL e, em seguida, acessar o valor. Veja o exemplo:
Boa sorte no projeto!
Olá André Celestino, bom dia
Por gentileza estou tentando realizar um comando mysql pelo delphi, mas dá erro, acredito que não estou acertando realizar as separações com aspas simples e duplas. Segue abaixo o codigo da rotina
LOAD DATA INFILE ‘C:/pasta/teste.txt’
INTO TABLE calcados
FIELDS TERMINATED BY ‘[TITULO]’
LINES TERMINATED BY ‘[FIM]’
(NOME, VALOR)
set ID = NULL, DATADISPONIBILIZACAO = DATE(NOW()), DISPONIBILIDADE = ‘SIM’;
Poderia me ajudar a montar esse comando no delphi, fiz da seguinte forma, mas acusa erro:
dmDados.SQLQueryImportacao.SQL.Add(‘INTO TABLE calcados’) ;
dmDados.SQLQueryImportacao.SQL.Add(‘FIELDS TERMINATED BY [TITULO] ‘) ;
dmDados.SQLQueryImportacao.SQL.Add(‘LINES TERMINATED BY [FIM]’) ;
dmDados.SQLQueryImportacao.SQL.Add(‘(NOME, VALOR)’) ;
dmDados.SQLQueryImportacao.SQL.Add(‘set ID = NULL, DATADISPONIBILIZACAO = DATE(NOW()), DISPONIBILIDADE = “SIM”‘);
Grato querido.
Bom dia, Anselmo, tudo bem?
Notei que a sua dúvida é um pouco mais avançada e precisa de um acompanhamento.
Vou entrar em contato por e-mail, ok?
Abraço!
boa tarde andre,
parabens pelo site
andre, estou fazendo um sistema simples de cadastro de cliente e nele tem uma dbgrid com os dados.
preciso criar uma busca neste dbgrid que ao começar a digitar vai filtrando os nomes que tem a expressao: exemplo
JOAO, ai aparece todos os registros que tem o JOAO no nome
estou usando um MDB do access, tenho Adoconection 1 Adotable e 1 DataSource ja tentei mas nao consigo
voce pode me dar uma ajuda?
obrigado
Boa tarde, Márcio, como vai?
Desculpe-me pela demora para respondê-lo.
Para filtrar registros em um DataSet, geralmente trabalhamos com as propriedades Filter e Filtered, porém, no momento não consigo confirmar se o TADOTable atualmente suporta filtros parciais com o operador Like, mas vale a pena fazer um teste.
Veja este tópico do Stack Overflow para tomar como base:
http://stackoverflow.com/questions/6799234/need-help-with-delphi-and-adotable-filtering
Abraço!
André
Estou estudando Delphi e me deparei com uma duvida
Estou fazendo um “select “select coluna1 from tabela”
O resultado desse select eu queria mostrar em um mesmo.
Ele deveria retornar todas as linhas da coluna1, mas quando eu coloco memo.text := fieldbyname(coluna1).asstring só me retorna a primeira linha da coluna1 que estou pesquisando.
Desculpa algum erro estou no celular
Olá, Sanmyo, como vai?
Para exibir os valores de todas as linhas, geralmente percorremos os registros em uma iteração (looping), como, por exemplo, com uma instrução while.
Veja o exemplo a seguir. Para cada iteração, o valor de “Coluna” é adicionado no componente TMemo.
Espero que lhe ajude.
Abraço!
Boa tarde!
Tenho uma dúvida, e se eu precisar passar valores para um parâmetro ‘IN’ na query?
Exemplo:
Query.ParambyName(‘CODIGO’).asInteger := Aqui eu precisaria passar os códigos que são inteiros.
Alguém sabe como fazer?
Olá, FabrÃcio!
Infelizmente o ParamByName não fornece suporte para cláusulas IN.
Neste caso, você deverá concatenar os valores manualmente e atribuir à propriedade SQL.Text da Query:
Para facilitar essa concatenação, você pode inserir os valores em objeto da classe TStringList e obtê-los separados por vÃrgula através da propriedade CommaText.
Abraço!
Boa noite Andre!
Pois é … desta forma eu sei que tem como, foi como eu fiz aqui … mas queria saber se tinha como utilizar o ‘IN’ utilizando o ParambyName. De toda forma muito obrigado pelo retorno!
Abraço!
Eu que agradeço pela visita e pelo feedback, Fabricio!
Abraço!
Boa Noite
André,
Amigo, estou tentando fazer uma SP no IbExpert – Firebird 2.5 para que mostre o dia da semana (segunda, terça e assim por diante…)
Está dando erro para salvar…
Onde pode estar o problema? Será este mesmo o comando???
Fico no aguardo.
Wander
Boa tarde, Wander, tudo bem?
Não tenho certeza, mas acredito que não é possÃvel retornar o dia da semana pelo SQL com o Firebird. Fiz um teste aqui e a função
dayName
não existe. Apenas oweekday
.Eu sugiro que você trabalhe com essa conversão na aplicação cliente, pois já existem métodos para essa finalidade. Retorne o
weekday
e exiba o nome do dia da semana utilizando a função dayofweek do próprio Delphi. Veja um exemplo no artigo abaixo:http://www.delphibasics.co.uk/RTL.asp?Name=dayofweek
Abraço!
Olá Wander,
se deseja trazer o dia da semana via BD você pode criar e utilizar a procedure abaixo:
Nossa, perfeito, Diego. Não tinha pensado nessa solução!
Muito obrigado pela colaboração! Vou enviar um e-mail para o Wander para notificá-lo da sua resposta.
Abração!
Bom dia André,
Parabéns pela iniciativa e constância em seus posts.
Tento juntar dados de dois bancos MDB com ADO. Estou utilizando XML com bom resultado, já vi algumas referencias a ISAM text mas não quis testar. Ouvi algo sobre SQL mas não sei como implementar.
O caso deveria ser trivial, trata-se de um aplicativo trabalhando stand-alone que capta uma ficha por exemplo, e deve ser exportada para o servidor na instituição. Atualmente gero o XML, mas gostaria de levar um backup do banco para poder filtrar não só quais dados, mas também quais campos, já que não sei fazer isso em XML.
Muito Obrigado
Teria algo sobre esse método usando SQL, caso em que traria um backup para ser importado.
Olá, Cláudio, tudo bem?
Peço desculpas pela demora para responder. Por algum motivo o seu comentário caiu na categoria de spams, mas consegui recuperá-lo.
Cláudio, a melhor forma de trabalhar com filtros de dados, ordenações e agrupamentos realmente é pela linguagem SQL. Os recursos dessa linguagem são poderosos para manipular dados.
Caso você não tenha nenhuma experiência com SQL, recomendo o curso gratuito da Softblue:
Link para o curso
Abraço!
Caro MESTRE,
Tenho uma QUERY que não atende os parametros passados em tempo de execução.
Se coloco um valor no parametro da query no modo design, este não se desfaz.
Se deixo este parametro “null”, a query retorna sempre VAZIA.
Firbeird 3.0
Firedac QUERY
Data Provider
ClientData Set.
Tabela PONTUACAO
campo NUMERORODADA é um varchar(11)
Parâmetro, pRodada recebe uma string por meio de uma VAR (NrRodada), declarada no Private do form como string
SQL IBExpert funciona blz.
Uso Delphi XE7
———–EIS o o codigo que executa.
===================== FIM
Dezenas e dezenas de tentativas com DICAS google, mas nada que resolvesse.
Abradeço.
Olá, Moacir!
Peço desculpas pela demora para respondê-lo. Por algum motivo, o seu comentário caiu na caixa de spams, mas consegui recuperá-lo.
Vou entrar em contato com você por e-mail, ok?
Abraço!
Boa tarde André,
Gostaria de saber como posso desenvolver um editor SQL para ter acesso as tabelas do meu sistema, e desta forma ter acesso e fazer manutenção em registro nas minhas tabelas do meu sistema.
Já naveguei em vários sites, e quero lhe dizer que no seu site um pouco que li sobre SQL é, em minha opnião, o site mais rico em explicação clara sobre programação.
Ronaldo Macena
Olá, Ronaldo, tudo bem?
Em primeiro lugar, agradeço pelo feedback sobre o blog 😉
Ronaldo, desenvolver um editor SQL não é algo simples, no entanto, também não é algo extremamente complexo.
Basicamente você terá um campo de texto para digitação do comando SQL (como um TMemo), uma Query para executar a SQL (como o TFDQuery ou TSQLQuery) e uma Grid para exibir o resultado (como o TDBGrid). Porém, é preciso se atentar a vários fatores, como transação, tipo do banco de dados, syntax highlighting, command parser e plano de execução.
Por conta destes itens, eu sempre sugiro a utilização de um editor já existente. O HeidiSQL, por exemplo, é um editor free, aberto e desenvolvido em Delphi 🙂
SqlDbx, RazorSQL e DBeaver também são ótimas opções. Para Firebird, considere também o IBExpert.
Abraço!
Boa tarde André,
Estou utilizando o Delphi XE8 com MySQL conectando com DBExpress.
Sabes alguma coisa sobre um problema ao executar um SELECT com WHERE no SQLDataSet?
Ao ativar o SQLDataset ou o ClienteDataSet aparece um erro de syntax no ‘as’ do apelido da tabela e no WHERE se remover o ‘as’. Penso ser um problema de incompatibilidade do Libmysql.DLL com os DBX. O que me diz?
A Libmysql.dll que utilizo é de 12/08/2011 com 2.304KB.
O mesmo erro aconteceu com a lib de 23/02/2010 com 2.304KB.
Esta última lib funciona perfeitamente no Delphi XE2.
Outras libs (mais novas) apresentaram problema de versão.
Olá, Brasa, tudo bem?
Não tenho conhecimento deste erro. Já trabalhei com Delphi + MySQL, embora com outras versões, e não me recordo de ter esbarrado com erros dessa natureza.
Talvez será necessário encontrar uma DLL que seja totalmente compatÃvel com o XE8, assim como a DLL para o XE2.
Eu gostaria de reproduzir este teste, mas tenho apenas as versões Berlin e Tokyo instaladas no meu ambiente.
Caso você tenha intenções de migrar para essas versões mais novas, poderei ajudá-lo melhor!
Abraço!
Olá, bom dia. Gostaria de saber como fazer um sum utilizando IBQuery ou FDQuery.
Grato se puder responder.
Olá, Messias, tudo bem?
Para executar um comando SUM em um componente TIBQuery, utilize a propriedade SQL.Text (ou SQL.Add, se preferir):
Já com o componente TFDQuery, é um pouco mais fácil. Basta informar a instrução SQL como parâmetro do método Open:
Abraço!
Muito obrigado, André, pela resposta.
Boa tarde André, tudo bem?
Sou iniciante em programação e mais ainda em Delphi, estou desenvolvendo uma aplicação bem simples para controle de impressoras, troca de toner e etc.
Parei em uma parte que está me deixando de cuca quente.
Quero fazer alguns updates em uma a partir de um edit, os dados dessa tabela serão fixos exceto por um campo com a quantidade que eu só quero fazer updates conforme entrada ou saÃda de toner.
Segue o código que fiz até agora, poderia ver se há algum erro por favor?
Tenho certeza que há algum erro, eu só não sei qual ainda, poderia me apontar por favor?
Estou usando o PostgreSQL com os drivers ODBC, TSQLConnection, TSQLDataSet, TDataSetProvider e TClientDataSet.
Desde já agradeço imenso.
Cordialmente.
Olá, Gabriel, tudo bem?
Ao analisar o código, identifiquei que o erro está na linha em que você cria o parâmetro “qnt”. O correto é dessa forma:
O que está em “qnt” será substituÃdo pelo valor do TEdit em tempo de execução.
Abraço!
Bom dia André, tudo bem?
Agradeço imenso a resposta, me ajudou muito, modifiquei algumas coisas no código e deu certo, veja como ficou:
Dessa forma funcionou bem.
Mais uma vez muito obrigado pela ajuda e atenção.
Parabéns pelo seu trabalho.
Cordialmente.
Olá, Gabriel.
Peço desculpas por não ter compreendido muito bem a sua necessidade. Analisando este novo código, entendi que você deseja somar a quantidade de um produto, e não sobrescrever a quantidade. O seu código agora está correto! Não tenho nada a acrescentar 🙂
Obrigado por retornar ao blog para enviar este comentário, Gabriel.
Grande abraço!
Boa noite André, fiquei muito feliz de encontrar o seu site, felizmente poucas pessoas estão disposta a ajudar como você. Sou iniciante em programação em Delphi e afins.
Estou com um problema num “select coditem, descitem, pesoitem, codLinhaItem, codSegItem from item”.
Esse select retorna todos os itens da tabela item, porem os dois últimos campos, retornam o código e preciso que retorne a descrição (que fica em outra tabela, sendo os dois campos chave primaria da mesma – não sei o pq disso, mas foi feito assim, rsrs).
Eu consigo fazer isso passando os parâmetros. Porém só pra um item por vez. Preciso de uma forma que retorne todos os itens da tabela itens.
Obrigado pela atenção. Abraços.
Olá, José, tudo bem?
O seu problema pode ser resolvido com a cláusula JOIN da linguagem SQL. Essa cláusula faz a junção de duas (ou mais) tabelas para trazer os seus valores de uma vez só.
Por exemplo, imagine que exista uma tabela chamada FORNECEDORES na qual possui o campo “CodigoCidade”. Caso seja necessário trazer o nome da cidade na SQL (que está em outra tabela – CIDADES), poderÃamos fazer dessa forma:
Observe a ligação entre as tabelas “Fornecedores” e “Cidades” através dos comandos INNER JOIN e ON.
Caso você queira usar algum recurso como base de estudo, recomendo o 1KeyData:
https://www.1keydata.com/pt/sql/
Abraço!
Olá, André!
Bela explicação… mais uma vez, me ajudou muito, e muito obrigado!
Abraço!!
Fico feliz em saber que o artigo lhe ajudou, Roberto!
Obrigado. Abraço!
Bom dia André!
Tenho um TSQLquery para fazer um filtro para o relatório de impressão está assim:
O problema que eu não estou conseguindo é que ele me mostre somente o registro que esta no Form. Ao invés disso ele puxa todos os registros da tabela! Em outras tabelas que eu tenho, consigo fazer normalmente este filtro.
Abraços! Feliz Natal!
Boa tarde André!
Consegui resolver! Depois de uma boa noite de sono, estava na minha cara o tempo todo e eu não vi, rsrsrs.
Na parte que estava assim:
Coloquei assim:
Funcionou de boa!
Abraços e um Feliz Natal!
Isso acontece mesmo, Roberto, rsrs.
Às vezes o erro está explÃcito, bem na nossa frente, mas o cansaço não nos permite identificá-lo. Basta apenas algumas horas de descanso para resolver.
Bom, de qualquer forma, o problema foi solucionado!
Abração!
Oi André tudo bem, gostaria muito que você tentasse me ajudar.
Gostei muito desse seu post porque é exatamente o meu problema, mas infelizmente eu não estou sabendo converter essa metodologia em Delphi para linguagem SQL que estou utilizando no meu código python.
Basicamente tenho três variáveis A,B,C que são passadas pela usuário, e quero utilizar elas no meu select, e já busquei infinidades de formas de resolver esse problema ainda sem solução.
Meu Select é esse, e ele está correto, só que apenas quando insiro já os valores nas “?” contidas nele:
E depois de tentar de muitas formas, atualmente estou com essa aqui, mas ainda sem sucesso:
Olá, Vinicius, bom dia!
Os pontos de interrogação na sua instrução SQL (“?”) pode ser substituÃdos por parâmetros na Query.
Como não tenho o projeto em mãos, vou sugerir um código, mas não tenho certeza se ele funcionará:
Se não funcionar, ou em caso de mais alguma dúvida, envie um e-mail para [email protected].
Abraço!
Parabéns André, e muito obrigado, estou iniciando meus estudos em DELPHI e sua matéria foi muito útil.
Obrigado, Thiago!
Desejo boa sorte nos seus estudos. A linguagem é fantástica!
Abraço!
Boa noite Andre!
Preciso de uma ajuda sua, poderia me dar um exemplo de como criar um select com a clasula “in” em tempo de execução no delphi?
sei usar no banco firebird mas quando coloco no delphi no Parambyname sei que nao funciona pq vi os comentarios acima, mas também nao sei resolver isso.
Se puder me ajudar, agradeço.
Bom dia, Josue, tudo bem? Peço desculpas pela demora.
Infelizmente não existe um comando “pronto” para montar cláusulas “IN” no Delphi. Uma forma de montá-las, na qual uso bastante, é utilizando o Format:
Para mais informações sobre o Format, acesse o Delphi Basics ou o DocWiki da Embarcadero.
Abração!
Olá André desejo que tudo esteja bem com você.
Por favor poderia me ajudar com um problema? Estou trabalhando com 3 tabelas onde eu estou varrendo a tabela 1 e a medida que encontro os dados referente a essa tabela, eu gravo nas tabelas 2 e 3. Após esse processo, gravo na tabela 1 o resultado encontrado nessas tabelas(2,3). já modifiquei o código para torna-lo o mais rápido possÃvel visto que são muitos registros, mas estou tendo problemas em manter o registro da tabela 1 “estacionado” enquanto procuro nas demais, pois quando eu edito e gravo o registro dessa tabela (1) ele avança um registro. Gostaria de uma maneira de “travar” nesse ponto e após todo o processo de gravação dos resultados, eu passe para o próximo registro (Utilizo ZeosLib com MySql e/ou MariaDB). Espero ter sido claro quanto a explicação, desde já obrigado. E Parabéns pelo Blog – Sempre recorro a seus artigos, ajuda bastante.
Olá, Edvaldo, tudo certo?
Creio que entendi o seu problema. O fato de você editar e gravar o registro não deveria fazer com que avançasse para o próximo registro. Há algo preenchido no
IndexFieldNames
ouIndexName
do DataSet? Suspeito que após a gravação o registro está sendo reordenado. Verifique também se há alguma chamada ao método “Next” após a gravação do registro (eventosBeforePost
ouAfterPost
).Se ainda não der certo, envie o código para “[email protected]” para que eu possa analisar melhor.
Abraço!
Bom dia André
Tenho uma duvida, quem sabe você possa me ajudar, seguinte:
Como faço para exibir está pesquisa em um Edit?
Testei e não deu certo:
Olá, Marcos, tudo bem?
O seu código está correto, e deveria trazer o valor da coluna “TOTAL”.
Qual erro ocorre quando você tentar utilizar essa instrução?
Tudo bem sim André, e com o senhor?
O erro que apresenta é:
Tenho que criar um field para ele? Como seria? Já que ele só existe na pesquisa.
Olá, Marcos!
Não, você não precisa criar um Field para esse campo. Os Fields são criados automaticamente quando o DataSet é aberto.
Vou entrar em contato com você. Abraço!
André, boa tarde. Creio que você irá me ajudar mais uma vez.
Estou com algumas query’s:
1 Query local SQLite – Smartphone
1 Query SQLite – Servidor
1 Query Sincronismo…
Eu pego as informações da query do servidor, como FILIAL para usar como Where CODFILIAL in (:pFILIAL)
Da query de sincronismo.
Sendo que tá estranho. Já tentei fazer quotedstr mas a string fica sempre com apóstrofos fechando a query.
Teria alguma forma de passar o result como um array para um parâmetro da query?
Pois tá complicado trabalhar com esse arranjado. Não consegui fazer funcionar ainda esse filtro pra não ter que trazer toda tabela para o celular.
Olá, Lucas, vou entrar em contato com você!
Abraço!
Parabéns. Bem explicado.
Muito obrigado, Wellington!
Abração!
O que há de errado nesta procedure que o relatório não obedece a cláusula “where” da instrução SQL?
Olá, Rui, tudo bem?
A sua instrução SQL está correta. Para ter certeza, antes de chamar o Preview, insira essa linha:
Você verá uma mensagem com a quantidade de registros após a execução da consulta. Se for 1, a consulta está correta.
Talvez o problema esteja na configuração do relatório. Recomendo também as seguintes ações:
1) Verifique se o relatório realmente está conectado ao componente FDM.qryMovimentos.
2) Verifique se há algum evento do RLReport1 que possa estar interferindo no resultado da consulta.
3) Faça o teste com outra query e verifique se ocorre o mesmo problema. Dessa forma você conseguirá isolar o problema.
Abraço!
Olá André, desculpa incomodar.
Inclui a linha sugerida e de fato mostra apenas 1 registro (o do id 3). Fiz outras cláusulas e sempre a caixa de mensagem indica o número de registros corretamente.
No entanto só consigo filtrar o registro se eu colocar diretamente na propriedade SQL da query a clausula “where id=5, como se as instruções de close, clear, add, etc do programa não funcionassem. Pelo que vi não é o relatório. Tem mais alguma sugestão. Imensamente grato.
Olá, Rui.
Bom, pelo relato, tenho a impressão de que não é a mesma query. Ou seja, o componente no qual você faz a consulta não é o mesmo componente que está conectado ao relatório.
Ou então, como mencionei anteriormente, algum evento antes de emitir o relatório está interferindo na consulta, mas é só um palpite.
Algo, no entanto, me chamou a atenção. Se a mensagem mostra apenas 1 registro, então a consulta de fato está sendo executada corretamente. Você inclusive pode adicionar um componente TDBGrid nessa tela de filtro e verificar que a consulta realmente traz o registro esperado. Isso só confirma, portanto, que o problema provavelmente está na configuração do relatório.
Abraço!
Olá André, tudo bem?. Espero que sim!.
Preciso de uma forma rsrs
Eu tenho um cadastro de cliente, campos: Razão social e CNPJ e estou com problemas na alteração de dados.
Eu usei um exemplo seu de QUERY com algumas adaptações a minha necessidade que funcionou muito bem para evitar duplicação de registro no banco de dados no meu caso CNPJ.
O meu código é:
Mas surgiu um problema. Quando coloco a tabela em modo de alteração e tento alterar somente a Razão Social retorna a mensagem dizendo que o CNPJ já consta na base de dados.
Teria como ajustar esse código para não retornar essa mensagem quando apenas altera a razão social?
Obs. Estou usando access e ADOQuery.
Boa tarde, Mailson!
Já estamos nos falando por e-mail. Abraço!
Então, mas se o banco for muito grande, não causaria travamentos?
Tive problemas com isso várias vzs, demorando alguns segundos pra destravar e/ou terminar a consulta.
Olá, xará, tudo bem?
Desconheço problemas de performance com o uso de parâmetros. Mesmo assim, deixo a minha contribuição: a consulta deve ser o mais refinado possÃvel para evitar problemas de travamento. Por exemplo, ao invés de recuperar 1000 registros, recupere apenas 100 (ou até menos). O usuário difÃcilmente vai visualizar ou trabalhar com vários registros ao mesmo tempo.
Temos feito esse tipo de refinamento em nossas consultas e melhorarmos bastante o desempenho da nossa aplicação.
Além disso, lembre-se de revisar cláusulas e condições que você utiliza nas instruções SQL. A remoção de um simples JOIN pode trazer segundos de diferença.
Abraço!
Os problemas que tive foram com consultar em um banco de saidas de NF-e.
Quando precisamos ver o faturamento mensal, por exemplo, o filtro vai pegar do dia 01 até a data atual (da consulta), ou num perÃodo pré-determinado em 2 DateTimePicker (data inicial / data final).
O “inconveniente”, no meu caso, é que a empresa que distribui o software de emissão de NF-e decidiu armazenar no mesmo banco os pedidos simples e CF-es.
Isso me obriga a adicionar um filtro de Espécie (coluna NF), Série (tipo de emissão -> 1 para NF-e / U para pedido simples / CF para cupons fiscais), além de precisar filtrar as NF-e que estão Canceladas e que ainda estão em Digitação.
Sendo assim, são muitos “ADD” dentro do Select.
Todo esse procedimento acaba sobrecarregando os recursos do BDE mesmo aumentando os parâmetros de configuração dentro do Database Engineer.
Talvez poderia ser desnecessário se fossem bancos diferentes para cada tipo de lançamento, mas a construção do formato/campos/colunas do DB é do fornecedor do software.
Outra dúvida que sempre tive (e que tbm tem me causado sobrecarregamento) é usar o OnChange de um Edit, pois a consulta fica se “reiniciando” a cada caracter digitado, tem alguma maneira de contornar isso?
Olá novamnente, André.
Bom, ao meu ver, quanto mais condições na consulta, melhor, já que elas filtram os registros que serão recuperados.
Talvez o seu problema seja o BDE, que já é considerada uma tecnologia relativamente obsoleta e de fato não suporta, com performance satisfatória, operações em grandes bancos de dados. Em outras palavras, o problema de performance parece estar mais relacionado à infraestrutura do que com o código Delphi em si.
A respeito do OnChange, tenha cautela! Não é uma boa prática executar uma consulta a cada caracter digitado. Isso realmente prejudica bastante a performance.
Para esse problema, eu tenho 3 sugestões:
1) Adicionar um botão “Pesquisar” ao lado do Edit, e executar a consulta somente quando este botão for pressionado.
2) Adicionar uma condição no evento OnChange para que a consulta seja executada a partir de X caracteres (por exemplo, 5 caracteres).
3) Adicionar um Timer na tela para que a consulta seja executada 1 segundo após o último caracter digitado. Neste caso, por exemplo, se o usuário digitar “ABCDE” (em menos de 1 segundo de intervalo entre as digitações), a consulta só será executada 1 segundo após o caracter “E” ser digitada. Se você observar, esse mecanismo já vem sendo utilizado por vários aplicativos. A barra de busca do iFood, por exemplo, funciona dessa forma.
Abraço!
Boa Tarde! Vê se vc consegue me ajudar. Onde faço a pesquisa tem mais de 5 mil registros, e a partir de uma certa quantidade de registros, eles aparecem na hora da consulta. Como faço para que na minha consulta apareça todos os registros? Percebi isso porque cadastramos um produto e quando fomos fazer uma consulta para adicioná-lo no pedido, ele apareceu para mim, sendo q o cadastro esta certinho. Ai percebi que tem muitos produtos que não estão aparecendo. Será que consegue me ajudar? Obrigada.
Olá, Vanessa.
Não tenho certeza se compreendi muito bem a sua dúvida.
A quantidade de registros que uma consulta retorna depende da instrução SQL que está sendo executada e também do valor que está definido na propriedade PacketRecords do DataSet. No entanto, sugiro que tenha cautela em consultas como essa. Trazer 5 mil registros de uma vez só (ou mais) sobrecarrega bastante tanto o banco de dados quanto a aplicação em si. A minha recomendação é criar filtros na tela para que o usuário possa aplicar critérios antes de executar a consulta, de forma que traga somente os registros que ele deseja.
Abraço!
no aplicativo desktop posso usar so query para consultas, insert, updates e deletes
Olá, Mauricio.
Não entendi se o seu comentário foi uma pergunta ou uma afirmação mas, sim, você pode usar o componente Query para o CRUD (consultas, inserções, atualizações e remoções), embora não da mesma forma que um DataSet. Com o componente Query, é melhor trabalhar com comandos SQLs (Select, Insert, Update e Delete) ao invés de Append, Edit e Post.
Abraço!