Autor Téma: Firebird - Select, hledání bez ohledu na diakritiku  (Přečteno 4497 krát)

Offline Petr P.

  • Nováček
  • *
  • Příspěvků: 26
  • Karma: 1
    • Verze Delphi: Turbo Delphi 2006
Potřeboval bych hledat v Selectu v podmínce Where bez ohledu na diakritiku (a  je jako á apod). Jde to nějak ?
« Poslední změna: 03-08-2018, 20:43:18 od Petr P. »

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2587
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #1 kdy: 03-08-2018, 22:15:37 »
Potřeboval bych hledat v Selectu v podmínce Where bez ohledu na diakritiku (a  je jako á apod). Jde to nějak ?
My na to mame nadefinovanou UDF funkci na strane Firebirdu a analogickou funkci na strane klienta a obe pouzijeme na prislusnych strana vyrazu ve where klauzuli.

Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 761
  • Karma: 43
    • Verze Delphi: 10.3
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #2 kdy: 03-08-2018, 23:55:37 »
Také UDF funkce a tatáž funkce na klientovi. Navíc pokud je prohledávaných záznamů hodně (miliony apod.), míváme kromě např. pole Prijmeni jeste indexované pole Prijmeni2, do kterého v triggeru ukládáme tu hodnotu bez diakritiky a pro vyhledávání se pak používá to pole Prijmeni2.

Zmiják

  • Host
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #3 kdy: 04-08-2018, 09:16:33 »
Excellent
Rated 1 time
Od FireBirdu v. 2.1 existuje přímé řešení bez potřeby UDF, speciálních sloupečků apod.

Hledejte "WIN_CZ_CI_AI" zde:
https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-appx06-charsets.html#fblangref25-appx06-tbl-charsets

U těch sloupečků, kde to chcete využít je třeba definovat znakovou sadu a řazení.
Můžete to udělat např. pomocí domény a tu potom použít při CREATE TABLE.
CREATE DOMAIN   D_JMENO         VARCHAR(50)   CHARACTER SET WIN1250 COLLATE WIN_CZ_CI_AI;
CREATE DOMAIN   D_PRIJMENI      VARCHAR(70)   CHARACTER SET WIN1250 COLLATE WIN_CZ_CI_AI;


Offline vandrovnik

  • Guru
  • *****
  • Příspěvků: 761
  • Karma: 43
    • Verze Delphi: 10.3
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #4 kdy: 04-08-2018, 11:15:40 »
Od FireBirdu v. 2.1 existuje přímé řešení bez potřeby UDF, speciálních sloupečků apod.

To se mi bohužel nějak nepovedlo přimět ke správnému řazení písmene "ch" - vždycky mi ho to dávalo pod "c", zatímco uživatelé očekávali, že ho najdou až za "h".

Offline Petr P.

  • Nováček
  • *
  • Příspěvků: 26
  • Karma: 1
    • Verze Delphi: Turbo Delphi 2006
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #5 kdy: 04-08-2018, 12:55:32 »
Ta UDF funkce je někde dostupná ?

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2587
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #6 kdy: 04-08-2018, 16:09:16 »
Ta UDF funkce je někde dostupná ?
Ta nase neni, protoze k ni nevlastnime dispozicni prava, ale je to funkce v DLL, ktera se da napsat v Delphi viz treba https://delphi.cz/post/64-bitove-UDF-v-RAD-Studio-XE2-pro-FireBird.aspx a v ni vyprasit nejakou funkci napr. ANSI kodovou stranku Win1250, v principu jako je tahle neoptimalizovana:
Kód: Delphi [Vybrat]
  1. function CzOff(CStr: PChar): PChar; cdecl; export;
  2.  const
  3.    CZ='ÁÄÂÉĚËÉÍÝÓÔÖŮÚÜŘŤŠŽĽĹŇČĎ';
  4.    US='AAAEEEEIYOOOUUURTSZLLNCD';
  5.  var
  6.    i,j:integer;  
  7. begin
  8.   CharUpperBuff(CStr, length(CStr));
  9.   for i:=0 to StrLen(CStr)-1 do
  10.   begin
  11.     for j:=1 to length(CZ) do
  12.       if CStr[i]=CZ[j] then
  13.       begin
  14.         CStr[i]:=US[j];
  15.         break;
  16.       end;
  17.    end;  
  18.   end;
  19.   Result:=CStr;
  20.  end;
  21.  

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2587
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #7 kdy: 04-08-2018, 18:24:32 »
Jeste jsem zapomel poslat tu deklaraci UDF na strane SQL:
Kód: SQL [Vybrat]
  1. DECLARE EXTERNAL FUNCTION CZOFF
  2.     CSTRING(255)
  3.     RETURNS CSTRING(255)
  4.     ENTRY_POINT 'CzOff' MODULE_NAME 'xxxUDF.DLL';
  5.  

Offline Petr P.

  • Nováček
  • *
  • Příspěvků: 26
  • Karma: 1
    • Verze Delphi: Turbo Delphi 2006
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #8 kdy: 04-08-2018, 18:34:49 »
Díky

Offline Jirka

  • Plnoletý
  • ***
  • Příspěvků: 146
  • Karma: 8
    • Verze Delphi: XE2
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #9 kdy: 06-08-2018, 19:16:40 »
Ahoj
Pouzivam toto :   

function VyhledejPodleNazvu(AText: String): integer;
    var
    Razeni,  ASql:string;
    begin
     if CheckboxDiakritika.Checked then
      Razeni:='COLLATE WIN_CZ_CI_AI' else Razeni:='';


     if  (Length(Trim(AText))>0) then
     ASQL:=Format('SELECT * FROM  VIEW_SKLAD_KARTA_KMEN WHERE (NAZEV_SKLPOL %s) CONTAINING %s ',[Razeni, (PridejUvozovkyAVrat(AText))])
    else
     ASQL:=Format('SELECT * FROM  VIEW_SKLAD_KARTA_KMEN ',[ ]);


    end;


Offline Petr P.

  • Nováček
  • *
  • Příspěvků: 26
  • Karma: 1
    • Verze Delphi: Turbo Delphi 2006
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #10 kdy: 07-08-2018, 18:50:15 »
Díky, tohle mi připadá jako lepší řešení než UDF.  Myslel jsem si před tím, že  COLLATE WIN_CZ_CI_A musí být nastavené u jednotlivých údajů v datábázi.
« Poslední změna: 07-08-2018, 18:53:18 od Petr P. »

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1429
  • Karma: 34
    • Pepak.net
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #11 kdy: 07-08-2018, 18:58:22 »
Oprav mě, jestli se mýlím, ale podle mě když COLLATION zadáš za běhu, tak se nebudou moci použít indexy.

Offline Jirka

  • Plnoletý
  • ***
  • Příspěvků: 146
  • Karma: 8
    • Verze Delphi: XE2
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #12 kdy: 08-08-2018, 16:53:21 »
IMHO
Pole kde vyhledávím podle diakritiky (např. název produktu) nejsou ve většině případů stejně zaindexované (alespoň u mě :-) )

Offline Palino

  • Nováček
  • *
  • Příspěvků: 2
  • Karma: 0
    • Verze Delphi: 7, XE, Seattle
Re:Firebird - Select, hledání bez ohledu na diakritiku
« Odpověď #13 kdy: 21-06-2019, 14:19:54 »
Pozdravujem vsetkych,

len pre zaujimavost aj ked takto neskoro: firebird umoznuje definovat indexy typu  COMPUTED BY definovane vyrazom napr. pre znakovu sadu WIN1250:

CREATE INDEX ADRESAR_IDX8 ON ADRESAR COMPUTED BY (nazov collate PXW_SLOV);
CREATE INDEX ADRESAR_IDX9 ON ADRESAR COMPUTED BY (nazov collate WIN_CZ_CI_AI);

ak zadate podmienku v tvare zadaneho vyrazu pouzije prislusny index :

select * from adresar a where a.nazov collate pxw_slov = 'peter' collate pxw_slov
select * from  adresar a where a.nazov collate WIN_CZ_CI_AI = 'peter' collate WIN_CZ_CI_AI


taktiez dobre vyuzitelne na hladanie napr cisel ktore maju byt pri porovnani orezanena zaciatocne nuly:

CREATE INDEX ADRESAR_IDX7 ON ADRESAR COMPUTED BY (trim (leading '0' from (upper(replace(ICO,' ', '')))));

select * from adresar a where trim (leading '0' from (upper(replace(a. ICO,' ', ''))))  = trim (leading '0' from (upper(replace(:ICO,' ', ''))))