Consulta Independente de acento

Delphi

03/04/2015

Gostaria de saber se é possível fazer uma consulta sem mexer no banco, pelo delphi mesmo, pesquisando palavras com acento mais sem escrever na pesquisa com acento.

Ex:
Pesquisa joao

Resultado joao, joão, JOÃO
Narba Silva

Narba Silva

Curtidas 0

Respostas

Narba Silva

Narba Silva

03/04/2015

Essas formas que você passou eu encontrei mais não me ajudam.

Assim, no meu banco existe o nome João salvo com acento, então ao consultar "joao" ele deveria buscar todos com ou sem acento no banco.

Com essas funções são trocados os acentos para a busca no delphi e nao no banco que vai continuar não trazendo o que quero.
GOSTEI 0
Marcos P

Marcos P

03/04/2015

O argumento original da pesquisa ( com acento) deve ser convertido por uma dessas funções e passado ao banco JUNTO com o argumento original... João + Joao.

Se for necessário tratar maiusculas faça mais uma função q converta os dois argumentos passando 4 parâmetros ao banco.... João + Joao + JOÃO + JOAO.

E, é isso...
GOSTEI 0
Narba Silva

Narba Silva

03/04/2015

Seria difícil você ou alguém me mostrar exemplos de como fazer ?

Para ignorar palavras maiúsculas e minusculas fiz assim:

 DM.DSet_Clientes.Close;
   DM.DSet_Clientes.SelectSQL.Clear;
   DM.DSet_Clientes.SelectSQL.Add('select * from clientes where UPPER(cli_nome) like  :nome');
   DM.DSet_Clientes.ParamByName('nome').AsString:= '%'+uppercase(edit_pesquisa.text)+'%';
   DM.DSet_Clientes.Open;



Vi lugares dizendo pra usar o ''AnsiUpperCase'' , para ignorar acentos, mais não deu certo.


Seria difícil me mostrar exemplos de como fazer com acentos?
GOSTEI 0
Marcos P

Marcos P

03/04/2015

Qualquer código de conversão baseado em funções do lado da aplicação, não vai descartar a necessidade de passar mais de um parâmetro de pesquisa, pois, no banco você tem todos os tipos de ocorrência.
Com acentuação...
Sem acentuação...
Maiúsculas...
Minúsculas...

Não consigo simular isso agora, mas pense em uma query com 4 parâmetros... pode ser uma solução.

Na sequência posso preparar algo de código.
GOSTEI 0
Ricardo

Ricardo

03/04/2015

Eu utilizo exatamente dessa forma com Firebird e MySQL perfeitamente; não importa se é maiúsculo, minúsculo e acentuado.

with query do
    begin
      close;
      sql.Clear;
      sql.Add('select campos from tabela');
      SQL.Add('where upper(campo) like upper('+ QuotedStr('%' + Edit.Text + '%'));
      sql.Add(')');
      sql.Add('order by upper(campo)');
      open;
    end;
GOSTEI 0
Narba Silva

Narba Silva

03/04/2015

O meu fiz no interbase 6.5 tem como eu passar pro firebird ?

Como fazer?
GOSTEI 0
Narba Silva

Narba Silva

03/04/2015

O meu fiz no interbase 6.5 tem como eu passar pro firebird ?

Como fazer?
GOSTEI 0
Ricardo

Ricardo

03/04/2015

O meu fiz no interbase 6.5 tem como eu passar pro firebird ?

Como fazer?


Firebird e Interbase são o mesmo banco, então creio que se você usar dessa forma que demonstrei não vai ter erros.

Tente ai e poste o resultado.
GOSTEI 0
Narba Silva

Narba Silva

03/04/2015

NÃO DEU CERTO.

MEU BANCO ES
GOSTEI 0
Narba Silva

Narba Silva

03/04/2015

NÃO DEU CERTO.

MEU BANCO ESTÁ COM EXTENSÃO GDB, SÓ PRA VOCÊS SABEREM NÃO SEI SE IMPORTA.

TENTEI FAZER O CÓDIGO ACIMA MAIS EM RELAÇÃO A MAIÚSCULA E MINUSCULA FUNCIONA , ACENTO NÃO

NO BANCO TEM Thaís e João.

Pesquiso thais e joao ele retorna nada.
GOSTEI 0
Ricardo

Ricardo

03/04/2015

NÃO DEU CERTO.

MEU BANCO ESTÁ COM EXTENSÃO GDB, SÓ PRA VOCÊS SABEREM NÃO SEI SE IMPORTA.

TENTEI FAZER O CÓDIGO ACIMA MAIS EM RELAÇÃO A MAIÚSCULA E MINUSCULA FUNCIONA , ACENTO NÃO

NO BANCO TEM Thaís e João.

Pesquiso thais e joao ele retorna nada.


Estranho, deveria funcionar! Então deve ser alguma coisa no Interbase.

Eu coloco aqui JOÃO e se procurar por JOÃO, JoãO, joao, joão, joÃO, JOAO etc... ele encontra normalmente.
GOSTEI 0
Marcos P

Marcos P

03/04/2015

Teabalhe do lado da aplicação com a função de retirada dos acentos. Monte a query com Upper nos dois parâmetros ( JOÃO e JOAO ) e trabalhe com OR na query.
Isso deve funcionar independentemente da configuração do banco...
GOSTEI 0
Narba Silva

Narba Silva

03/04/2015

Desculpe a ignorancia talvez mais assim, como posso criar uma função que vai pegar uma palavra sem acento e acha-la com acento ?

Pois por exemplo a função troca áàãâ por a , agora como pesquisar joao e a função saber troca o a por ã e não por áàâ???


Se não tem exemplo ?


Pesquisei sobre Collate, mais dai teria que mexer no banco e não sei se compeça
GOSTEI 0
Marcos P

Marcos P

03/04/2015

Você está confundindo as coisas...

Para a sua pesquisa, pelo q vc definiu no início do post, áãââá é igual a aaaaa, assim como joão é igual a joao.

Não se trata, portanto, de por acentos.... mas sim tirá-los.

Você deve pegar o código Delphi aí de cima e adaptá-lo para passar dois argumentos... o original e o sem acentos.

Vou tentar achar um micro aqui, para lhe passar um exemplo....
GOSTEI 0
Marcos P

Marcos P

03/04/2015

Não, vou conseguir uma maquina com Delphi... então vai no celular mesmo !

Crie uma função no Delphi para retirar os acentos ( uma dessas que eu coloquei no início ) e adapte o código que o Ricardo passou, para...

with query do
    begin
      close;
      sql.Clear;
      sql.Add('select campos from tabela');
      sql.Add('where upper(campo) like upper('+ QuotedStr('%' + Edit.Text + '%'));
      sql.Add(')');
      sql.Add('OR');
      sql.Add('upper(campo) like upper('+ QuotedStr('%' + FUNCAO_DELPHI_TIRAR_ACENTOS(Edit.Text) + '%'));
      sql.Add(')');
      sql.Add('order by upper(campo)');
      open;
    end;


O "OR" é que vai fazer com que você consiga recuperar os vários tipos ocorrências de "JOÃO"... joão, JOÃO, joao e JOAO.

Agora, se vc quer recuperar as mesmas ocorrências a partir de "JOAO", vai precisar existir um tratamento no momento de gravar os registros o banco ( eliminando os acentos ) ou uma função similar do lado do banco que permita fazer...

with query do
    begin
      close;
      sql.Clear;
      sql.Add('select campos from tabela');
      sql.Add('where upper(FUNCAO_BANCO_TIRAR_ACENTOS(campo) like upper('+ QuotedStr('%' + FUNCAO_DELPHI_TIRAR_ACENTOS(Edit.Text) + '%'));
      sql.Add(')');
      sql.Add('order by upper(campo)');
      open;
    end;


Essa sim, uma solução completa.

Pena não ter uma máquina aqui pra testar, mas deve funcionar.

Boa sorte !
GOSTEI 0
Marcos P

Marcos P

03/04/2015

Consegui fazer um exemplo, todo do lado do banco ( sql server, no caso... )

Dê uma olhada em : SQL Server - Fiddle
GOSTEI 0
Narba Silva

Narba Silva

03/04/2015

Não veja o primeiro post.

Ex:
Pesquisa joao

Resultado joao, joão, JOÃO


Eu quero que no banco fique salvo como o usuário salvar, com acento, sem acento, maiúsculo ou minusculo.

E na pesquisa, no caso de existir registrado João (com acento) e Joao (sem acento ) , por exemplo, na hora que em eu pesquisar ''joao'' (minusculo e sem acento )

ele me retorna João e Joao.

A função vai tirar os acentos na palavra pesquisada, mais se a palavra pesquisa nao tiver acento ele nao vai trazer ''João" (com acento).

Então teria que ser uma função que consiga tratar os registro do banco e não da pesquisa, como voce mostrou, mais essa função seria criada dentro do banco?

with query do
    begin
      close;
      sql.Clear;
      sql.Add('select campos from tabela');
      sql.Add('where upper(FUNCAO_BANCO_TIRAR_ACENTOS(campo) like upper('+ QuotedStr('%' + FUNCAO_DELPHI_TIRAR_ACENTOS(Edit.Text) + '%'));
      sql.Add(')');
      sql.Add('order by upper(campo)');
      open;
    end;
GOSTEI 0
Marcos P

Marcos P

03/04/2015

Viu o exemplo q passei no Fiddler ?

Ele faz exatamente o q vc quer... joao, recupera :

João
JOAO
joao
JOÃO
joão

Já q seu banco tem todos os tipos de ocorrência e vc vai ter todos os tipos de entrada na aplicação, vc vai precisar ter o tratamento na aplicação e no banco !

Considere os exemplos q postei...
GOSTEI 0
Narba Silva

Narba Silva

03/04/2015

É que eu nunca fiz, existe forma entao de fazer função dentro do banco de dados?
GOSTEI 0
Marcos P

Marcos P

03/04/2015

Sim... o IB / FB, assim como a grande maioria dos SGBDs, permite a criação de funções pelo usuário.

Dê uma olhada em :

https://www.devmedia.com.br/7-utilizando-e-criando-udfs-no-firebird-interbase/4848

http://www.firebirdsql.org/en/writing-udfs-for-interbase/
GOSTEI 0
Renato Rubinho

Renato Rubinho

03/04/2015

Buenos,

Se usar o LIKE e substituir os caracteres acentuados por "_" tbm funciona.

    Edit.Text := 'João';
    for i:=1 to Length(Edit.Text) do
      if Pos(Copy(Edit.Text,i,1),'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') = 0 then
        Edit.Text := Copy(Edit.Text,1,i-1) + '_' + Copy(Edit.Text,i+1,Length(Edit.Text));

    with query do
    begin
      close;
      sql.Clear;
      sql.Add('select campos from tabela');
      SQL.Add('where upper(campo) like upper('+ QuotedStr('%' + Edit.Text + '%'));
      sql.Add(')');
      sql.Add('order by upper(campo)');
      open;
    end;
GOSTEI 0
Marcos P

Marcos P

03/04/2015

E aí cara, resolveu teu problema ?
GOSTEI 0
Narba Silva

Narba Silva

03/04/2015

No final das contas achei melhor refazer o banco.

Refiz ele coloquei charset Win1252 collate winPTBR.


Fazendo isso, usando o UPPER na sql já resolve.

   DM.DSet_Clientes.Close;
   DM.DSet_Clientes.SelectSQL.Clear;
   DM.DSet_Clientes.SelectSQL.Add('select * from clientes') ;
   DM.DSet_Clientes.SelectSQL.Add('where upper(cli_nome) like upper('+ QuotedStr('%' + edit_pesquisa.Text + '%')+ ')');
   DM.DSet_Clientes.SelectSQL.Add('order by upper(cli_nome) ') ;
   DM.DSet_Clientes.Open;



Obrigado a todos pela ajuda!!!
GOSTEI 0
POSTAR