Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: MySQL: Kirjainkoosta riippuva haku

Sivun loppuun

pistemies [29.04.2016 14:47:54]

#

Miten voisi tietokanta haussa tunnistaa suuret ja pienet kirjaimet?
Esimerkiksi haku 'apple' ei löytäisi sanaa 'Apple'?

Metabolix [29.04.2016 16:12:43]

#

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.

pistemies [30.04.2016 13:08:53]

#

Yep.
Teksti sarakkeiden kollaatio on utf8_general_ci.
Vaikuttaako tuo jälkimmäinen hakutyyppi tähän toivotulla tavalla?

Grez [30.04.2016 13:22:34]

#

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

Metabolix [30.04.2016 13:39:16]

#

Grez, muuten hyvä, mutta tuollaista ei ole MySQL:ssä. (Latin1-merkistölle löytyisi.)

Mahdollisia kollaatioita voi tutkia kyselyllä SHOW COLLATION (LIKE "%").

Grez [30.04.2016 15:35:05]

#

Ok, no sitten se ei tietenkään ole vaihtoehto :D

pistemies [30.04.2016 17:34:08]

#

Voiko tuota name = BINARY 'teks' soveltaa sql- LIKE hakuun:

"name LIKE '%" . $word . "%'";

Metabolix [01.05.2016 21:24:46]

#

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

pistemies [01.05.2016 22:23:48]

#

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.

Metabolix [01.05.2016 22:26:37]

#

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.

pistemies [01.05.2016 22:44:05]

#

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.

Metabolix [02.05.2016 16:21:25]

#

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?

pistemies [02.05.2016 21:07:25]

#

Kiitos. Nyt sain tuon BINARYn oikeaan kohtaan.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta