Převod kódování MySQL

Školení, která pořádám

Pokud chcete změnit kódování dat uložených v databázi, nestačí k tomu jeden příkaz ALTER DATABASE, protože ten změní kódování pouze u nově vytvářených tabulek. Úlohu vyřeší posloupnost příkazů ALTER TABLE s modifikátorem CONVERT TO. Pokud je tabulek hodně, určitě by se na to vyplatilo napsat skript.

Skutečný problém ale nastává v případě, kdy jsou data v databázi např. v kódování latin2, ale MySQL si myslí, že jsou v kódování latin1. Potom zdánlivě všechno funguje, ovšem jen do té doby, dokud se nemá porovnávat nebo třídit. Pokud bychom se kódování pokusili přímo změnit, dojde k převodu z jednoho kódování na druhé, jehož výsledkem bude spousta neexistujících znaků. Kódování je nejprve nutné změnit na binary (což nezpůsobí žádnou konverzi) a poté na cílové kódování (což opět nezpůsobí žádnou konverzi). Nejde k tomu ovšem použít modifikátor CONVERT TO, protože ten sloupce v kódování binary nepřevádí, a kódování je nutné změnit u jednoho sloupce po druhém. K tomuto převodu jsem si napsal následující skript:

<?php
if ($argc != 3 || !mysql_select_db($argv[1])) {
    exit("Usage: php $argv[0] db collation\n");
}
$db = idf_quote($argv[1]);
$collation = $argv[2];

function idf_quote($idf) {
  return "`" . str_replace("`", "``", $idf) . "`";
}

function mysql_convert($query) {
    echo "$query;\n";
    $return = mysql_query($query);
    echo mysql_error();
    return $return;
}

mysql_convert("ALTER DATABASE $db COLLATE $collation");
$result = mysql_query("SHOW TABLES");
while ($row = mysql_fetch_row($result)) {
    $table = idf_quote($row[0]);
    $binary = array();
    $utf8 = array("COLLATE $collation");
    $result1 = mysql_query("SHOW COLUMNS FROM $table");
    while ($column = mysql_fetch_assoc($result1)) {
        $type = $column["Type"];
        if (preg_match('~char|text|enum|set~', $type)) {
            $field = idf_quote($column["Field"]);
            $default = mysql_real_escape_string($column["Default"]);
            $binary[] = "MODIFY $field $type CHARACTER SET binary";
            $utf8[] = "MODIFY $field $type COLLATE $collation" . ($column["Null"] == "YES" ? "" : " NOT NULL") . ($default != "" && $default != "NULL" ? " DEFAULT '$default'" : "");
        }
    }
    mysql_free_result($result1);
    if ($binary) {
        mysql_convert("ALTER TABLE $table " . implode(", ", $binary));
    }
    mysql_convert("ALTER TABLE $table " . implode(", ", $utf8));
}
mysql_free_result($result);
?>

Skript pomocí příkazů SHOW TABLES a SHOW COLUMNS získá seznam všech sloupců a změní jejich kódování. Kromě toho změní i kódování všech tabulek (kvůli nově přidávaným sloupcům) a databáze. Pro připojení k databázi můžete použít direktivy mysql.default_* nebo si ho doplnit na začátek skriptu. Pokud preferujete vypsání převodních příkazů (pro kontrolu a následné ruční provedení), změňte funkci mysql_convert tak, aby příkazy vypisovala.

Jak uvádí MySQL Performance Blog, tak binární sloupce nemohou být součástí fulltextových indexů. Skript by tedy bylo potřeba upravit tak, aby indexy nejdřív odstranil a po konverzi zase vytvořil.

Škoda, že MySQL nepodporuje nějaké výchozí kódování, které by znamenalo „zděď od rodiče“, všechno by pak bylo o poznání jednodušší.

Přijďte si o tomto tématu popovídat na školení Návrh a používání MySQL databáze.

Jakub Vrána, Řešení problému, 7.11.2005, diskuse: 52 (nové: 0)

Diskuse

Jan Brašna:

Já to provádím tak, že vezmu dump, proženu ho normálním převodem a vrátím ho zpět (a nezapomenu správně nastavit nové prostředí db a tabulí).

Michal:

Když jde o dump celého MySQL s mnoha databázemi a tabulkami různých uživatelů a aplikací, kde pomalu platí, že co tabulka to jiné kódování, tak není převod pomocí dumpu příliš schůdný.

Petr Maizner:

zdravim,
kdyz uz jste u toho kodovani. mam maly problem v php vs. mysql.
mam mysql verze 4.1.15 na windows 2000. cela databaze a tabulky jsou v kodovani cp1250_general_ci (v my.ini mam take
default-character-set=cp1250).
PHP stranky mam take v kodovani charset=windows-1250.
Pokud provedu update nebo insert v databazi v teto konfiguraci, objevi se mi hlaska "File 'c:\mysql\share\charsets\?.conf' not found (Errcode: 22) Character set '#26' is not a compiled character set and is not specified in the 'c:\mysql\share\charsets\Index' file", nicmene dotaz se v porakdu provede. Netusite nekdo jak se teto hlasky zbavit ? Nasel jse tu hlasku mockrat na netu ohledne teto konfigurace ale zadne reseni.
PS: c:\mysql\share\charsets\ mam soubor index.xml i cp1250.xml.

diky za radu pm

Brm:

A jeje ... tohle jsem resil asi pred rokem, a nakonec (co si pamatuju) pomohlo zkopirovani toho adresare charsets (nebo jenom nekterych souboru?) ze starsi verze.

Kazdopadne (definitivne) jsem to vyresil tak, ze jsem presel na UTF8.

Brm:

Trosku googlovani, a kupodivu reseni jde najit tady:)

http://dev.mysql.com/doc/refman/5.0/en/pro…-character-sets.html

Bohumír Bednařík (BoboCop):

Přesně ten stejný problém jsem řešil taky a myslím si, že se mi ho podařilo vyřešit.

Viz popis problému
http://www.bobocop.cz/blog/136741_item.php
a jeho řešení
http://www.bobocop.cz/blog/136880_item.php

Petr Tomenendál:

Zdravím,
díky za užitečný skript.
Jde podstatně zrychlit spojením více volání "alter table" pro jednu tabulku do jednoho dotazu. MySQL pak provede všechny změny na jedné dočasné kopii tabulky místo toho, aby pro každé volání "alter table" vytvářelo novou dočasnou tabulku.

Hlavní část skriptu pak může vypadat takto:
<?php
while ($row = mysql_fetch_row($result)) {
    $sql=$sql_new=array();
    mysql_convert("ALTER TABLE $row[0] COLLATE $collation");
    $result1 = mysql_query("SHOW COLUMNS FROM $row[0]");
    while ($row1 = mysql_fetch_assoc($result1)) {
        if (preg_match('~char|text|enum|set~', $row1["Type"])) {
            $sql[]="MODIFY $row1[Field] $row1[Type] CHARACTER SET binary";
            $sql_new[]="MODIFY $row1[Field] $row1[Type] COLLATE $collation" . ($row1["Null"] ? "" : " NOT NULL") .
                ($row1["Default"] && $row1["Default"] != "NULL" ? " DEFAULT '$row1[Default]'" : "");
        }
    }

    if (sizeOf($sql)) {
        $sql="ALTER TABLE $row[0] ".implode(',',$sql);
        mysql_convert($sql);
        $sql_new="ALTER TABLE $row[0] ".implode(',',$sql_new);
        mysql_convert($sql_new);
    }
}
?>

Snad se to zobrazilo správně. :)
PT

ikona Jakub Vrána OpenID:

Kdyby náhodou někoho stejně jako mě napadlo, že by to mohlo jít spláchnout dokonce jedním dotazem, tak to nejde. Na příkaz

ALTER TABLE x MODIFY a varchar(20) CHARACTER SET binary, MODIFY a varchar(20) COLLATE cp1250_czech_cs;

řekne MySQL:

ERROR 1054 (42S22) at line 6: Unknown column 'a' in 'x'

ikona Jakub Vrána OpenID:

Díky, skript jsem upravil tak, aby se nekladlo zbytečně moc dotazů. Ještě má tyhle problémy:

- nefunguje s fulltextovými indexy
- ve sloupcích typu char, které nejsou zcela zaplněny textem, nechává na konci \0

Jirka:

Zdravím,
je to tak, že se nastavením COLLATE (u databází a tabulek) automaticky nastaví i defaultní CHARACTER SET?

ikona Jakub Vrána OpenID:

Ano.

Jirka Šachl:

Řeším závažný problém. Mám server založený na redakčním systému e107. Upgradoval jsem na novou verzi systému, ale celý systém spadl kvůli rozdílným názvům datových polí. Databáze je uložena na webzdarma, je to mysql a přistupuji k ní cestou phpmyadmin. Zálohoval jsem databázi a provedl instalaci nové verze. Stará verze serveru používala kódování češtiny ISO 8859-2, nová verze UTF-8. Zkouším cestou phpmyadmina dostat do databáze všechny data ve správném kódování češtiny ale již jsem vyčerpal všechny možnosti a stále mi na stránkách lezou paznaky. Ke konverzi používám PSpad. přikládám struktůru jedné tabulky.

-- Struktura tabulky `e107_forum`
--

DROP TABLE IF EXISTS `e107_forum`;
CREATE TABLE IF NOT EXISTS `e107_forum` (
`forum_id` int(10) unsigned NOT NULL auto_increment,
`forum_name` varchar(250) collate latin2_czech_cs NOT NULL default '',
`forum_description` text collate latin2_czech_cs NOT NULL,
`forum_parent` int(10) unsigned NOT NULL default '0',
`forum_sub` int(10) unsigned NOT NULL default '0',
`forum_datestamp` int(10) unsigned NOT NULL default '0',
`forum_moderators` text collate latin2_czech_cs NOT NULL,
`forum_threads` int(10) unsigned NOT NULL default '0',
`forum_replies` int(10) unsigned NOT NULL default '0',
`forum_lastpost_user` varchar(200) collate latin2_czech_cs NOT NULL default '',
`forum_lastpost_info` varchar(40) collate latin2_czech_cs NOT NULL default '',
`forum_class` varchar(100) collate latin2_czech_cs NOT NULL default '',
`forum_order` int(10) unsigned NOT NULL default '0',
`forum_postclass` tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (`forum_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin2 COLLATE=latin2_czech_cs AUTO_INCREMENT=18 ;

Omlouvám se za delší příspěvek. Napadá někoho řešení ?

Honza:

Mohl bys použít funkci iconv?
<?php
   $newStr
= iconv( 'iso-8859-2', 'utf-8', $oldStr);
?>
Tím bys měl mít šanci to přemigrovat.

eTomm:

Ahoj,
nerozumim jak se mam připojit k databázi.
když dám na začátek skriptu:
mysql_connect("mysql", "xxx.xxx.cz", "xxx");
tak to nefunguje...
nikde nemužu najít co znamenají pole $argc a $argv
co ještě musim nastavit aby to fungovalo?
Díky

TBarina:

$argc=pocet argumentu
$argv=pole argumentu

Script je psany tak, aby byl spousten z prikazove radky. Pod win to musite dat jako parametr php.exe, pod Linuxem sh php xxxx. Ja jsem si v Linuxu musel dohrat balicek php-cli pro podporu php z prikazove radky, protoze casto byva php jen jako modul Apache.

gorn:

<?php mysql_connect("mysql", "xxx.xxx.cz", "xxx"); ?>

je spatne, podle dokumentace na http://cz2.php.net/manual/en/function.mysql-connect.php je spravne neco jako

<?php mysql_connect("xxx.xxx.cz", "jmenouzivatele", "heslo"); ?>

Podrobnosti viz ta dokumentace (pokud mate mysql na stejne masine tak na prvnim miste zkuste "localhost")

Jozef:

Ani nevieš, ako si mi pomohol. Neviem takmer nič o PHP ani MySQL. Začal som pracovať s TYPO3 a prvýkrát som prenášal databázu z lokálneho servera na Internet. Všetko prebehlo bez problémov až na tú diakritiku. Namiesto nej všade dva ?? Po niekoľkodňovom hľadaní pomoci na Internete a skúšaní rôznych doporučených postupov som narazil na tvoju stránku a tvoj skriptík pomohol. Musel som tu original databazu prekonvertovat z latin1_swedish na utf8. Preniesol som ju na Internet a uz je to OK. Dalo mi to dost zabrat, nez sa to podarilo. Cele to okolo toho kodovania je poriadne zamotane pre mna zaciatocnika.
Vdaka za pomoc.

franta:

Mam podobny problem

Znaková sada v MySQL: UTF-8 Unicode (utf8)
porovnavani cp1250_general_ci

co doporucujete zmenit?

kiiv:

pouzivam v mysql verze 4 a vejs sql dotaz v php:  set character set ....  (podle znakove sady v jake je stranka)
pokud nejsou data blbe ulozeny bude to fungovat bez problemu

stepanek:

Na serveru je mysql 3.23.47 , stránku mám v utf8, tabulku také v utf8 (data), zde je to v pohodě.
Problém č. 1
Zároveň, ale potřebuji číst data z jiné tabulky, která je v ISO-8859-2.
Samozřejmě mi to místo českých znaků vrací "?". Zkoušel jsem různé nastavení SET charset, která na těchto stránkách byla uváděna, ale bez výsledku (asi za to může verze mysql). Nevěděl by jste nědo řešení ?
Problém č.2
Data z tabulka, která je v utf8, mi to třídí česky špatně.
"Č","ě". ... je až na konci abecedy. Opět je na vině verze mysql, nebo je i pro toto nějaké řešení ?

ikona Jakub Vrána OpenID:

Rozumná podpora znakových sad, obzvlášť vícebajtových, je k dispozici až od MySQL 4.1.

hu:

dobrý den, potřebuji také v phpmyadmin změnit tabulky v databázi z latin2 na utf8, ale jsem v tomto totální amatér. poraďte prosím vás s řešením. mám hosting na blueboard.cz.

problém je: latin2 mám v databázi a utf8 v souborech nové verze wordpressu. když použiji latin2, tak se diakritika na vlastním webu zobrazuje správně, ale nefunguje admin rozhraní (lze se přihlásit do systému, ale nemohu publikovat ani nic jiného), naopak s utf8 funguje admin, ale diakritika na stránkách ne. nevím si s tím rady..

Marco:

Snazim sa urobit konverziu z latin1_swedish do utf8 (utf8_general_ci, utf8_slovak_ci) ale vysledok je (priklad):
povodna hodnota: ahoj čajka
nova hodnota: ahoj
Cize odreze vsetko od pozicie kde je prvy znak s diakritikou.
Konverzia do cp1250 ide ok, ale toto nie. Vie niekto poradit?

d.f.h:

dík. tohle mi zachránilo když ne život, tak určitě nervy.

Diego:

Muže te mi někdo poradit jak to mam aplikovat ?
mam phpbb a potřebuji to dat do UTF8
JSEM takřka Lama
děkuji
Ps: uvítal bych tecnika na forum ICQ 114940059

gorn:

prelozil jsem gro tohoto clanku a umistil do dokumentace typo3, kam se velmi hodi: http://wiki.typo3.org/index.php/Talk:UTF-8_support ... pokud by to autorovi vadilo, tak necht mi promine a muj prispevek smaze (je to wiki)

kk:

AHoj.
Mam PHP server 5.2.0-8, mysql server 5.0.32 a cele je to na serveru Apache/2.2.3 (Debian)
a nasledujici problem :)

snazim se prevest nas intranet na kodovani UTF-8 a narazil jsem na zajimavou vec.
dejme tomu ze toto:

<?php
   
@$spojeni=mysql_connect("localhost","user","pwd");
   if (!$spojeni):
     echo "<p>Při načítání obrázků pro banner došlo k chybě číslo : ".mysql_errno()."<br>";
     echo "Text chybového hlášení : ". mysql_error()."<br>";
   endif;
?>

je cely muj script, je ulozen v UTF-8 v mysql mam nastaveny systemove promene na UTF-8
v php mam default_charset na utf-8, apache ma taktez nastaveno adddefaultcharset UTF-8
v metatagu stranky nastaveno taktez UTF-8

a ted mi prosim nekdo poradte proc vysledek v prohlizeci vypada takto :

Při načítání obrázků pro banner došlo k chybě číslo : 1049
Text chybového hlášení : Nezn -B? datab? 'db'

Uz si fakt nevim rady jak zmenit kodovani tech hodnot co vraci funkce mysql_error()

ma nekdo jakykoliv napad ? Budu vdecny za cokoli. Predem diky KK

ikona Jakub Vrána OpenID:

Tohle se pokud vím řídí locales. Jestli nepomůže nastavení na cs_CZ.UTF-8, tak asi jedině překódování té hlášky pomocí iconv.

kk:

ja vim ze se mozna budu hloupe ptat, ale jak se locales nastavuji?
na konzoli serveru kdyz zavolam locale tak vidim ze vsechny promenne jsou nastavene na UTF-8
ve zminenem scriptu jsem pomoci fce setlocale zkousel nastavit na cs_CZ.UTF-8 ... bez uspechu

navic kdyz si tam pres ECHO vypisu promenou $LANG tak v ni je znak "C" - coz nevim co znamena

Dik za napady KK

kk:

Tak jsem to vyresil,
sice asi ne uplne standardne ... ale zatim mi to staci ... a az bude cas ..... :)
jde o to ze ty chybovy hlasky pochazej z mysql ... konkretne jsem je nasel ulozeny v souboru errmsg.sys v /usr/share/mysql/czech/ a ten je kompilaci souboru errmsg.txt, ktery je v latin2
jsem jen vzal zdroj prevedl ho na UTF-8 a znovu zkompiloval a jede to

KK

ikona David:

to co pises je moc hezke, ale wokna mi pisi ze zadany prikaz neni zadny spustitelny. nikde na netu jsem nenasel zkompilovany soubor s cestinou v cp-1250. pouzivam to v internim systemu a ten byl delan v cp-1250 a tak s tim uz ted nejde nic delat a tak zda by jsi to mohl zkompilovat na cp-1250 a poslat nebo dat odkaz kde se da stahnout jiz zkompilovany byl bych ti moc vdecny.

Diky David
david@sopouskovi.eu

ikona Čuga:

mam takovy problemek...

provadim dump z mysql 5.neco do mysql 4.neco...

nic extra sem nenastavoval... do db mi uklada redakcni system, ktery uklada v utf-8 ale krome š a ž... a to je ten problem... v dupmu db je kodovani spravne, ale kdyz dam import do nove db, tak misto š a ž jsou vsude otazniky...

any idea??? thx

DoubleThink:

Většinou to dělám tak, že DUMP (který je v UTF8) převedu ICONVem:

UFT8 -> {kódování nastavené} = {kódování skutečné}

Ondřej Surý:

Tak jsem s tím zápasil docela dlouho a jediné funkční řešení, které jsem nakonec objevil je:

root@heathen:~# mysql --default-character-set=utf8 forum < forum-nocharset.dump
root@heathen:~# mysqldump forum > forum-correct.dump

Testováno na punbb tabulkama, které byly vytvořeny jako latin1 a potřeboval jsem z nich udělat utf-8.

Houbeless:

Zdravím,
chtěl bych tento skript použít k převodu znakové sady db latin1_swedish_ci na latin2_czech_cs - do db se připojim, vypíše mě tabulky, ale nic neprovede, mohl by mi někdo poradit jak ho prakticky použít? A kdyžtak trochu polopatisticky, prosím, ne pouze jednou větou:) Velice děkuji. H.

Pavel Křupala:

Ahoj,... vtipná situace... chci to v utf, ale nemůžu změnit tabulky :-D. Pouzivam 2 databaze (svou utf, aby se s tim dalo pracovat):

tady je db kterou nemuzu menit
- SHOW VARIABLES like 'collation%'
collation_connection    latin1_swedish_ci
collation_database    cp1250_general_ci
collation_server    cp1250_general_ci
- SHOW VARIABLES like 'character_set%'
character_set_client    latin1
character_set_connection    latin1
character_set_database    cp1250
character_set_filesystem    binary
character_set_results    latin1
character_set_server    cp1250
character_set_system    utf8
character_sets_dir    /usr/local/share/mysql/charsets/

a moje databaze samozrejme pouziva:
- SHOW VARIABLES like 'collation%'
collation_connection    latin1_swedish_ci
collation_database    utf8_general_ci
collation_server    cp1250_general_ci
- SHOW VARIABLES like 'character_set%'
character_set_client    latin1
character_set_connection    latin1
character_set_database    utf8
character_set_filesystem    binary
character_set_results    latin1
character_set_server    cp1250
character_set_system    utf8
character_sets_dir    /usr/local/share/mysql/charsets/

A pomoci PHP pracuji se svou databazi v utf normalne, ale pripojim se k te druhe, kde nemuzu nic menit a z boha z ni nemuzu dostat data v normalni podobe... (utf) Diky za odpoved

mail:pavel.krupala@gmail.com

ikona Jakub Vrána OpenID:

Pokud jsou data uložena v jiném kódování, než si myslí databáze, a nejde to změnit, tak bych doporučoval nastavit SET NAMES binary a převést to u klienta např. pomocí iconv().

Josef Eliáš:

Mám podobný problém... ať nastavím DB jak chci nekomunikuje s výstupem... na výstupu v prohlížeči nedokáže poslat české znaky... nenapadá mě řešení. Pevný text na stránce se zobrazuje dobře ale cokoliv příjde z DB je ve formě mezer a otazníků prosím o radu na nomad.007@seznam.cz

Simonka:

Ahojte, kto mi pomôže s týmto ? Mám redakčný systém a databázu MySQL kopmlet v UTF-8,všetko OK,  ale často zobrazujem dáta z Oracle v cp1250, cez funkcie oci8 a tam to nezobrazuje správne, dá sa s tým ničo robiť ? Ďakujem za info.

Kajman:

Pro univerzálnost, by měly být raději hodnoty v $row[0] a $row1[Field] obaleny zpětnými apostrofy, ať se to nevyseká, když má někdo zákeřně nazvané sloupce či tabulky.

ikona Jakub Vrána OpenID:

Ano a ještě zdvojeny zpětné apostrofy v názvu. Skript předělám a tohle tam zohledním.

Kajman:

Funkce idf_quote se volá před deklarací.

Scremsi:

Pomoc vsetko fungovalo snazil som sa to nedavat na server kde bolo ine kodovanie nez win mam utf a uz som chybu aj napravil ale vsetky nastavenia su na UTF8 ale aj tak to neide ja sa to na ...

Martin Černík:

používám e107 na webzdarma a kódování stránke je utf-8. Problém je v zobrazování času a data, když mám:
setlocale(LC_ALL,'cs_CZ'); - čas a dny jsou ok, ale znaky chybné
a při setlocale(LC_ALL,'cs_CZ.utf-8'); je vše zase anglicky. Existuje nějaká možnost na webzdarma to nastavit tak aby to šlo česky v utf-8? Díky moc

Kajman:

Do admineru by se asi něco takového nehodilo, že?

Nebo kdyby šlo třeba v admineru navolit u exportu, aby cucal data s charsetem nastaveným na binary, tak by pak snad stačilo prozkoumat sql soubor, v jakém je kódování a připsat mu na začátek správné set names.

ikona Jakub Vrána OpenID:

Také jsem o tom přemýšlel, ale asi to tam nakonec nedám.

Možnost určit kódování by to chtělo hlavně u CSV importu.

Shelley:

Do you understand that this is high time to receive the <a href="http://bestfinance-blog.com">loan</a>, which will make your dreams come true.

Martin Šustek:

Používám teď něco podobného pro hromadné přidávání komentářů k existujícím sloupcům (doplnění dokumentace do velké databáze).

Jen jsem si všiml, že v ALTER TABLE ... MODIFIY ... dotazech chybí $row1['Extra'], u textových hodnot to nejspíš nevadí, ale jinak se tím ztratí informace jako auto_increment, on update CURRENT_TIMESTAMP apod.

Forever:

Pohrál jsem si s tím Vaším scriptem. Nejdříve jsem totiž nemohl přijít na to jak se to vlastně používá, tak snad jsem to upravil tak, aby použití bylo dostatečně jednoduché. Případné opravy a vylepšováky možné.

<?php

/** SCRIPT NA PŘEVOD KÓDOVÁNÍ V MYSQL, původně od Jakuba Vrány, přepsáno mnou **/

/*  Nakonfiguruj a vlož příkaz pro připojení k databázi.
    Skript se má spustit ve třech krocích (viz $phase).
    phpmyadmin a adminer pak musí ukazovat správně diakritiku.
    Spořádání českých znaků musí správně fugovat, dám li řadit podle textového pole nebo varchar.
*/

function mysql_convert($query) {
    echo "$query;\n<br>";
    $return = mysql_query($query);
    echo mysql_error()."<br>";
    return $return;
}

$db_name = "pozice";
$target_collation[1] = "latin1_swedish_ci";
$target_collation[2] = "utf8_czech_ci";
$target_collation[3] = "utf8_czech_ci";
$target_character_set[1] = "latin1";
$target_character_set[2] = "binary";
$target_character_set[3] = "utf8";
$phase = 3; // zadej číslo kroku

/* SEM ZADEJ PŘIPOJENÍ K DATABÁZI */

mysql_select_db($db_name); mysql_error();
mysql_convert("ALTER DATABASE $db_name COLLATE $target_collation[$phase]");

$result = mysql_query("SHOW TABLES");
while (
$row = mysql_fetch_row($result)) {

  if ( $phase == 1 ) mysql_convert("ALTER TABLE $row[0] CONVERT TO CHARACTER SET $target_character_set[$phase] COLLATE $target_collation[$phase]");

  if ( $phase > 1 ):
    mysql_convert("ALTER TABLE $row[0] COLLATE $target_collation[$phase]");
    $result1 = mysql_query("SHOW COLUMNS FROM $row[0]");
    while ($row1 = mysql_fetch_assoc($result1)):
        if (preg_match('~char|text|enum|set~', $row1["Type"])):
            mysql_convert("ALTER TABLE $row[0] MODIFY $row1[Field] $row1[Type] CHARACTER SET $target_character_set[$phase]");
            mysql_convert("ALTER TABLE $row[0] MODIFY $row1[Field] $row1[Type] COLLATE $target_collation[$phase]" . ($row1["Null"] ? "" : " NOT NULL") . ($row1["Default"] && $row1["Default"] != "NULL" ? " DEFAULT '$row1[Default]'" : ""));
            "";
        endif;
    endwhile;
  endif;
}
mysql_free_result($result);
?>

patoj:

hojj Forever skusal som ten skript ,ale vyhadzuje mi chybovu hlasku

ALTER DATABASE pozice COLLATE utf8_czech_ci;
Can't create/write to file '.\pozice\db.opt' (Errcode: 2)

Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result resource in C:\xxxx\xxx\xxx\xxx\index.php on line 33

Warning: mysql_free_result(): supplied argument is not a valid MySQL result resource in C:\xxxx\xxxx\xxxx\xxxx\index.php on line 49

patoj:

Hojjte tak vyriesene sorac zabudol som zmenit dbname

oooohhh ja LAMA.:-)))

script funguje perfektne.

bobo:

Zdravím.
Mám podobný problém s převoden db do utf-8 jak zde již bylo zmíněno. Obsah db je tvz. v "bordelu". Je to staré fórum, které bych teď potřeboval oživit.
Scriptík v úpravě Forevera mi v druhém kroku odstraní všechny znaky od prvního výskytu "ěščřž" - zkrátka texty zmizí. Texty jsou z 90% ve Win1250, zbytek iso-8859-2. Porovnání latin2_czech_cs.
Moc bych potřeboval poradit co dělám blbě, či co je důvodem odříznutí znaků.
Díky

Vložit příspěvek

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2014 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.