Minulla on mysql-taulut utf-8 muodossa. Millainen mysql-taulun aakkosjärjestys-asetus tulisi olla, jotta se tulostuisi oikein? Nyt esim. Ö-alkuiset merkkijonot tulostuu alkupäässä, heti A-kirjaimilla alkavien jälkeen.
MySQL:n vaihtoehdoista suomea lähinnä on ruotsi (utf8_swedish_ci).
Ei tunnu auttavan tuokaan...
Ja tämä on niinku näin:
$lause = "SELECT * FROM Linkit WHERE osasto='$osasto' AND alaosasto='$alaosasto' AND alinosasto='0' ORDER BY otsikko ASC";
Tulostaa tuon alaosaston asiat. Miten muitten asetusten taulussa tulee olla?
kokeile:
mysql_set_charset('utf8',$link);
https://www.php.net/manual/en/function.mysql-set-charset.php
Jos olet jo luonut taulun väärin, sinun pitää varmaan vaihtaa collation jokaiselle tekstisarakkeelle erikseen.
Nuo sarakkeet oli väärin. Muutin ne (utf8_swedish_ci).
Sellainen muutos tapahtui, että ö-alkuiset merkkijonot tulostuu ylimpänä ennen A:ta.
geijo: Käytän PDO:ta, tuo ei taida sopia kunnolla yksiin sen kanssa.
Herää myös epäilys, että olet perinteiseen tapaan mokannut koko tietokanta-asian ja tallentanut UTF-8-dataa latin1-yhteyden yli kantaan, jolloin tietokannassa on itse asiassa ö-kirjaimen sijaan ö. Määritteletkö missään vaiheessa yhteyden merkistöksi UTF-8:a? PDO:ssa voit käyttää tähän kyselyä SET NAMES utf8.
Tuo vika siinä tosiaan on. Testailin asiaa muuttamalla erään rivin tekstiä phpmyadmissa.
Lisäsin tuon SET NAMES utf8 sivun alkuun. Tulostaa oikein.
Uusi ongelma. Miten saisin nopeasti taulun kaikilla riveillä päivitettyä nuo ääkköset oikein? Ei viitsi yksitellen joka rivillä joka kirjainta muuttaa... :)
Kokeile tätä:
UPDATE taulu SET asia = CONVERT(BINARY(CONVERT(asia USING latin1)) USING utf8);
Kannattaa ehkä ensin SELECT-versiolla kokeilla, että tulos on toivottu.
pistemies kirjoitti:
Lisäsin tuon SET NAMES utf8 sivun alkuun. Tulostaa oikein.
Voit laittaa tuon suoraan kun luot yhteyden kantaan, esim :
try { $yhteys = new PDO( 'mysql:host=palvelin;dbname=tietokanta', 'tunnus', 'salasana', array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8") } catch (PDOException $e) { die("Databasevirhe: " . $e->getMessage()); }
...niin on varmasti aina käytössä.
Metabolix kirjoitti:
Kokeile tätä:
UPDATE taulu SET asia = CONVERT(BINARY(CONVERT(asia USING latin1)) USING utf8);Kannattaa ehkä ensin SELECT-versiolla kokeilla, että tulos on toivottu.
Ei tämä muuttanut mitään merkkejä, kokeilin sitä näin:
$sql = "UPDATE Linkit SET otsikko = CONVERT(BINARY(CONVERT(otsikko USING latin1)) USING utf8)"; $dbh->exec($sql);
En jaksa nyt miettiä MySQL-magiaa juuri tuohon tapaukseen. Aina menee turhan hankalaksi, kun pitäisi korjata viallista dataa sen sijaan, että vain muutettaisiin taulun merkistö toiseksi.
Helppo ratkaisu ainakin on kierrättää data uudestaan PHP:n kautta:
// Sillä lähtee, millä on tullutkin: $db->exec("SET NAMES latin1"); $data = $db->query("SELECT id, otsikko FROM taulu")->fetchAll(); // Sitten korjataan tilanne ja laitetaan data takaisin: $db->exec("SET NAMES utf8"); $q = $db->prepare("UPDATE taulu SET otsikko = ? WHERE id = ?"); foreach ($data as $rivi) { $q->execute(array($rivi["otsikko"], $rivi["id"])); }
Kiitos kuitenkin sinulle!
Tämä "vika" johtuu juuri siitä, että olen siirtynyt uuteen parempaan systeemiin PDO:hon. Taulu, jossa merkit on virheellisiä, on ollut (tosin toisen nimisenä), käytössä useita vuosia. Olen pelkästään kopioinut sen ja muokannut sarakkeiden nimiä ja taulun ominaisuuksia tähän uuteen systeemiin sopivaksi.
Olenkin tätä ajanut "vanhanaikaisesti" vähän tuohon tapaan omalta admin-lomakkeelta.
$otsikko = utf8_decode($_POST['otsikko']); $kuvaus = utf8_decode($_POST['kuvaus']);
Tuo on minulla tallennusvaiheessa, mutta sen olisin voinut tietysti tehdä myös siihen kohtaan, kun rivejä aukaistaan lomakkeelle.
Tuo on lähes joka tilanteessa väärä ratkaisu. Jos merkistöt on asetettu oikein, dataa ei pitäisi joutua itse muuttamaan merkistöstä toiseen.
Joo, kyllä tämä on alunperin väärin tehty taulu. Sen olen tehty suunnilleen vuonna 2005. Siihen aikaan loin taulut aina php-skriptillä. Netistä löytyneitten php-oppaitten mukaan. Niissä kaikissa(?), myös Ohjelmointiputkassa, SQL-lause on tältä osin puutteellinen, taululle ei aseta mitään COLLATE-merkistöjä. Ohjelma luo sille oletuksena latin1_swedish_ci merkistön.
Eihän nyt ollut enää collationista puhe vaan tuosta virheellisestä datasta, jota olet virheellisellä enkoodauksella laittanut kantaan ja typerällä purkkaratkaisulla yrittänyt korjata. Toistan vielä: utf8_decode-funktiota ei pitäisi juuri koskaan joutua käyttämään. Yhdessäkään kunnollisessa oppaassa ei varmasti väitetä sitä ratkaisuksi merkistöongelmiin.
Metabolix kirjoitti:
Eihän nyt ollut enää collationista puhe vaan tuosta virheellisestä datasta, jota olet virheellisellä enkoodauksella laittanut kantaan ja typerällä purkkaratkaisulla yrittänyt korjata. Toistan vielä: utf8_decode-funktiota ei pitäisi juuri koskaan joutua käyttämään. Yhdessäkään kunnollisessa oppaassa ei varmasti väitetä sitä ratkaisuksi merkistöongelmiin.
No sattuuhan sitä paremissakin piireissä.
Tuolla sain sen kuiten korjattua, joten homma siltä osin Ok.
Aihe on jo aika vanha, joten et voi enää vastata siihen.