Consulta no mesmo Edit, mais de um termo contido no mesmo campo.

19/10/2023

0

Estou iniciando na programação DELPHI, e estou com uma dúvida.

Seguinte:
- Preciso digitar mais de um termo concatenado com *;
- Onde seja retornado num grid os produtos que contem esses termos digitados.

EXEMLPLO: CAI*CONT*TAMPA*PRE (digitados num Edit)
Produto desejado: Caixa Organizadora Container 56 Litros C/Tampa e Trava Preta 25793PM Arqplast

este produto assim como outros pode conter parte do(os) termos digitado(os).


Grato por quem puder me ajudar.
Valdenilson Lopes

Valdenilson Lopes

Responder

Post mais votado

19/10/2023

No banco de dados, para pesquisar por textos como "CAI*CONT*TAMPA*PRE", você precisa utilizar o LIKE

Porém, no banco, ao invés de "*", você deve utilizar "%": CAI%CONT%TAMPA%PRE%

Outro problema é que seu banco pode ser configurado com algum tipo de encoding que respeite a capitalização, diferenciando letras maiúsculas de minúsculas (caixa alta vs caixa baixa).

Então, se a coluna NOME_PRODUTO vale "Caixa Organizadora Container 56 Litros C/Tampa e Trava Preta 25793PM Arqplast"

Você teria que procurar usando:

  select ...
  where
    upper(NOME_PRODUTO) like upper('CAI%CONT%TAMPA%PRE%')


Se o texto buscado não inicia o nome do produto, tem que adicionar mais um símbolo de "%" no início.

  select ...
  where
    upper(NOME_PRODUTO) like upper('%CAI%CONT%TAMPA%PRE%')


Porém, já adianto que consultas desse tipo não são eficientes, porque tem que ler todos os registros da tabela.

Se você quer utilizar "*" ao invés de "%", pode fazer a substituição dentro da aplicação, ou no banco.

  select ...
  where
    upper(NOME_PRODUTO) like upper(replace('*CAI*CONT*TAMPA*PRE*','*','%'))

Arthur Heinrich

Arthur Heinrich
Responder

Mais Posts

19/10/2023

Valdenilson Lopes

No banco de dados, para pesquisar por textos como "CAI*CONT*TAMPA*PRE", você precisa utilizar o LIKE

Porém, no banco, ao invés de "*", você deve utilizar "%": CAI%CONT%TAMPA%PRE%

Outro problema é que seu banco pode ser configurado com algum tipo de encoding que respeite a capitalização, diferenciando letras maiúsculas de minúsculas (caixa alta vs caixa baixa).

Então, se a coluna NOME_PRODUTO vale "Caixa Organizadora Container 56 Litros C/Tampa e Trava Preta 25793PM Arqplast"

Você teria que procurar usando:

  select ...
  where
    upper(NOME_PRODUTO) like upper(''CAI%CONT%TAMPA%PRE%'')


Se o texto buscado não inicia o nome do produto, tem que adicionar mais um símbolo de "%" no início.

  select ...
  where
    upper(NOME_PRODUTO) like upper(''%CAI%CONT%TAMPA%PRE%'')


Porém, já adianto que consultas desse tipo não são eficientes, porque tem que ler todos os registros da tabela.

Se você quer utilizar "*" ao invés de "%", pode fazer a substituição dentro da aplicação, ou no banco.

  select ...
  where
    upper(NOME_PRODUTO) like upper(replace(''*CAI*CONT*TAMPA*PRE*'',''*'',''%''))



Entendo quando vc diz que não é eficiente, porém, bastante usual conforme eu mesmo vivenciei em uma softhouse que trabalhei.
Como eu faria na pratica? como eu colocaria no OnChange do TEdit ?

Hoje estou usando dessa forma, porem busca na sequencia de digitação, e nao em um todo (toda a descriçao dos produtos).

DM.DataSetProdutosMatriz.SelectSQL.Strings[9] :=
''WHERE p.inativo = ''''N'''' and p.descricao CONTAINING '' +
QuotedStr(EditPesquisa.Text) + '' AND L.DESCRICAO CONTAINING '' +
QuotedStr(EditBuscaLinha.Text) + '' AND F.DESCRICAO CONTAINING '' +
QuotedStr(EditBuscaFabricante.Text);

Onde o "EditPesquisa" é o Edit onde irei digitar os termos que preciso.

Abaixo está meu select no DataSet

SELECT P.codigo_produto, p.codigo_linha,
f.descricao as fabricante,
l.descricao as linha,
P.descricao,
p.unidade,
P.codigo_barra
FROM PRODUTOS p
inner join linhas l on l.codigo_linha = p.codigo_linha
inner join fabricantes f on f.codigo_fabricante = p.codigo_fabricante
....
Responder

20/10/2023

Valdenilson Lopes

Consegui pegar aqui a logica e ta funcionando bem,.Resolvido
Obrigado pela ajuda.

Ficou assim:
DM.DataSetProdutosMatriz.SelectSQL.Strings[9] :=
'WHERE p.inativo = ''N'' and p.descricao LIKE replace(''*'+EditPesquisa.Text+'*'',''*'',''%'') ';
Responder

20/10/2023

Arthur Heinrich

Como eu disse, é uma maneira ruim de resolver este problema. Ainda mais quando a query possui joins e você filtra desta forma, simultaneamente em múltiplas tabelas.

Com o passar do tempo, o tamanho destas tabelas vai crescendo e o número de usuários e pontos do sistema onde se utiliza isso também. Ou seja, o futuro é o apocalipse.

Sou especialista em tuning e, como você mesmo comentou, costuma ser uma prática comum. O que mais vejo são bancos destruídos por consultas livres para o usuário consultar o que quer. No dia em que o banco não aguenta, o desenvolvedor diz: Sempre foi assim e funcionava até ontem. Por isso, não pode ser esta query...

Se você quer implementar algo do tipo, evite sobrecarregar o banco. Tente transferir esse esforço para a camada da aplicação, que pode ser executada em um pool de máquinas ou mesmo na máquina do usuário. Deixe o banco, que roda de forma centralizada, para fazer o que é o necessário: atender às regras de negócio e não as vontades do usuário.

De quantos produtos estamos falando? 100 mil? Com nomes de 1000 caracteres? Isso dá 100 MB ou menos.

Você pode construir uma estrutura em memória, uma espécie de cache, onde você carrega a lista de produtos e, à medida que o usuário digita a busca, você varre esta lista e retorna os primeiros 10 que dão match, por exemplo.

Daí, quando o cliente escolhe o produto, você utiliza o ID_PRODUTO para filtrar sua tabela no banco.

Programar tem a ver com criar soluções. Não espere que elas venham como recurso nativo da linguagem.
Responder

20/10/2023

Valdenilson Lopes

Como eu disse, é uma maneira ruim de resolver este problema. Ainda mais quando a query possui joins e você filtra desta forma, simultaneamente em múltiplas tabelas.

Com o passar do tempo, o tamanho destas tabelas vai crescendo e o número de usuários e pontos do sistema onde se utiliza isso também. Ou seja, o futuro é o apocalipse.

Sou especialista em tuning e, como você mesmo comentou, costuma ser uma prática comum. O que mais vejo são bancos destruídos por consultas livres para o usuário consultar o que quer. No dia em que o banco não aguenta, o desenvolvedor diz: Sempre foi assim e funcionava até ontem. Por isso, não pode ser esta query...

Se você quer implementar algo do tipo, evite sobrecarregar o banco. Tente transferir esse esforço para a camada da aplicação, que pode ser executada em um pool de máquinas ou mesmo na máquina do usuário. Deixe o banco, que roda de forma centralizada, para fazer o que é o necessário: atender às regras de negócio e não as vontades do usuário.

De quantos produtos estamos falando? 100 mil? Com nomes de 1000 caracteres? Isso dá 100 MB ou menos.

Você pode construir uma estrutura em memória, uma espécie de cache, onde você carrega a lista de produtos e, à medida que o usuário digita a busca, você varre esta lista e retorna os primeiros 10 que dão match, por exemplo.

Daí, quando o cliente escolhe o produto, você utiliza o ID_PRODUTO para filtrar sua tabela no banco.

Programar tem a ver com criar soluções. Não espere que elas venham como recurso nativo da linguagem.


Muito boa sua esplanação amigo.
Top de verdade... Agradeço demais sua ajuda nessa tarefa.
Por mais pessoas assim, como vc!

Gostam de ajudar, tiram um tempo seu para ajudar o proximo.

E outra, conhecimento não deve ficar escondido, limitado.

parabens.
Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar