Miten voisi tietokanta haussa tunnistaa suuret ja pienet kirjaimet?
Esimerkiksi haku 'apple' ei löytäisi sanaa 'Apple'?
Vertailu riippuu kollaatiosta. UTF-8:ssa oletuskollaatio on utf8_general_ci, ja suomen kielen tapauksessa sopii utf8_swedish_ci. Näissä kirjainten koolla ei ole merkitystä. Sen sijaan kollaatiossa utf8_bin merkkien täytyy osua täsmälleen.
SELECT * FROM taulu WHERE sarake COLLATE utf8_bin = "teksti";
Vastaavaan tulokseen pääsee BINARY-sanalla.
SELECT * FROM taulu WHERE BINARY sarake = "teksti";
Huono puoli tässä on, että myös eräät muut vertailut muuttuvat. Esimerkiksi yksittäinen merkki "ä" (U+00E4) ja yhdistelmämerkki "ä" (U+0061, U+0308) ovat binäärivertailussa eri merkit, kun taas utf8_swedish_ci tunnistaa ne samaksi merkiksi.
Yep.
Teksti sarakkeiden kollaatio on utf8_general_ci.
Vaikuttaako tuo jälkimmäinen hakutyyppi tähän toivotulla tavalla?
Se vaikuttaa siihenkin juuri samoin kuin Metabolix viestissään kertoi. Eli merkkien binääriarvojen täytyy osua täsmälleen. Emme tiedä mikä tarkalleen on "toivottu tapa". Jos haluat nimenomaan erottaa isot ja pienet kirjaimet mutta et muuten samaan niputettuja kirjamia, niin silloin vaihtoheto voisi olla "COLLATE utf8_general_cs"
ci siis on "case insensitive" eli kirjainkoosta riippumaton ja
cs siis on "case sensitive" eli kirjainkoosta riippuva
Grez, muuten hyvä, mutta tuollaista ei ole MySQL:ssä. (Latin1-merkistölle löytyisi.)
Mahdollisia kollaatioita voi tutkia kyselyllä SHOW COLLATION (LIKE "%").
Ok, no sitten se ei tietenkään ole vaihtoehto :D
Voiko tuota name = BINARY 'teks' soveltaa sql- LIKE hakuun:
"name LIKE '%" . $word . "%'";
Toimii myös LIKE-haussa, kuten olisit voinut itse testata.
SELECT "ABC" LIKE "%b%"; -- 1, kirjainkoko ei merkitse SELECT "ABC" LIKE BINARY "%b%"; -- 0, kirjainkoko merkitsee SELECT BINARY "ABC" LIKE "%b%"; -- 0, kirjainkoko merkitsee
En oikein ymmärrä miten tuon sovittaa tähän pitkään haku-lauseeseen.
Tässä karkea lainaus minun lisäyksellä:
if (!empty($data['filter_name'])) { $implode = array(); $words = explode(' ', trim(preg_replace('/\s+/', ' ', $data['filter_name']))); foreach ($words as $word) { $implode[] = "pd.name BINARY `pd`.`name` LIKE '%" . $this->db->escape($word) . "%'"; } if ($implode) { $sql .= " " . implode(" AND ", $implode) . ""; } //---
Tällaisenaan ei tomi, joten hommat ei ole minulla tuossa ihan oikein.
Alkuperäiseen lausekkeeseen ei tarvitse kuin lisätä yksi ainoa BINARY-sana ennen kutakin kohtaa, jonka käsittelyä haluat muuttaa. Nyt olet selvästikin säveltänyt jotain ihan muuta.
sinun koodi:
SELECT BINARY "ABC" LIKE "%b%";
Minun alkuperäinen koodi tätä haun sql-lausetta koskien:
$implode[] = "pd.name LIKE '%" . $this->db->escape($word) . "%'";
Miten tätä pitäisi muuttaa?
ps. Ennen tätä kohtaa tiedostossa on yli 50 riviä hakutoimintoon liittyvää koodia.
pistemies kirjoitti:
Miten tätä pitäisi muuttaa?
Kerrataanpa vielä:
Metabolix kirjoitti:
ei tarvitse kuin lisätä yksi ainoa BINARY-sana
Eli jos haluat, että pd.name
käsitellään kuvaamallasi tavalla, kirjoita sen eteen BINARY
.
Toisin sanoen vaihda pd.name
:n tilalle BINARY pd.name
.
Pitääkö ohje toistaa vielä jollain muulla sanamuodolla?
Kiitos. Nyt sain tuon BINARYn oikeaan kohtaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.