PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : utf8_unicode_ci und PREPARE Statements


CeBe
03.06.2009, 18:58:31
Moin Leute!

auf MySQL 5.4 und 5.1.34 getestet.

Die Problematik verfolgt mich nun schon mehrere Wochen. Das Problem tritt, soweit ich es bisher eingrenzen konnte mit Prozeduren auf, die PREPARE-Statements verwenden, ich vermute allerdings, dass es noch irgendwo im Server eine versteckte Config übersehen hab.
Der SQL-Query wird in folgender Reihenfolge ausgeführt:
SET NAMES 'utf8' COLLATE 'utf8_unicode_ci';

USE testdb;

CALL proc_statistic_list_activities_select ( '5' , '0000-00-00 00:00:00' , '2009-06-03 17:02:20' , 5 );

dieser wirft folgenden Error:

ERROR 1267 (HY000): Illegal mix of collations (utf8_general_ci,COERCIBLE) and (utf8_unicode_ci,COERCIBLE) for operation '<>'

Meine Config:
mysql> SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

mysql> SHOW VARIABLES LIKE 'collation%';
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_unicode_ci |
| collation_database | utf8_unicode_ci |
| collation_server | utf8_unicode_ci |
+----------------------+-----------------+
3 rows in set (0.00 sec)


Auszug aus /etc/mysql/my.cnf

[mysqld]

[...]

# encoding settings

default-character-set=utf8
default-collation=utf8_unicode_ci
character-set-server=utf8
collation-server=utf8_unicode_ci
character-set-server=utf8
collation-server=utf8_unicode_ci



Obwohl in der my.cnf die default-collation=utf8_unicode_ci gesetzt ist, findet sich in der Tabelle information_schema.COLLATIONS ein Eintrag bei Default auf utf8_general_ci und alle Tabellen in der Datenbank mysql und information_schema sind auf utf8_unicode_ci gesetzt.

mysql> SELECT * FROM information_schema.COLLATIONS;
+--------------------+--------------------+-----+------------+-------------+---------+
| COLLATION_NAME | CHARACTER_SET_NAME | ID | IS_DEFAULT | IS_COMPILED | SORTLEN |
+--------------------+--------------------+-----+------------+-------------+---------+
[...]
| utf8_general_ci | utf8 | 33 | Yes | Yes | 1 |
| utf8_bin | utf8 | 83 | | Yes | 1 |
| utf8_unicode_ci | utf8 | 192 | | Yes | 8 |
[...]
| binary | binary | 63 | Yes | Yes | 1 |
+--------------------+--------------------+-----+------------+-------------+---------+
30 rows in set (0.00 sec)


Wenn noch Infos fehlen, einfach nachfragen!

Bin für jeden Ansatz dankbar!

MfG
Carsten

Damir
03.06.2009, 23:38:55
Hallo Carsten,

hier sollte es eigentlich erklärt werden - bin allerdings auch nur kurz rüber geflogen:

http://dev.mysql.com/doc/refman/5.1/en/charset-repertoire.html

Damir

CeBe
04.06.2009, 01:15:25
hier sollte es eigentlich erklärt werden - bin allerdings auch nur kurz rüber geflogen:

http://dev.mysql.com/doc/refman/5.1/en/charset-repertoire.html
Danke für den Link, das hilft mir aber nicht weiter...

Es geht ja darum, dass ich gerade das nicht brauche, da ich NUR mit utf8_unicode_ci arbeite, was auch in allen Config-Variablen steht. Somit dürfte eigentlich kein utf8_general_ci auftauchen...

MfG
Carsten

CeBe
04.06.2009, 02:30:06
Bin dem Problem ein bisschen näher gekommen...
Wenn ich eine Funktion anlege:
DELIMITER //

CREATE FUNCTION `func_select_statistic_module_name_statistic_module_id`(
`v_statistic_module_id` int
) RETURNS varchar(50)
READS SQL DATA
BEGIN

[...]

RETURN v_name;

END
//

verändert MySQL die Funktion folgendermaßen: (rot)

SHOW CREATE FUNCTION func_select_statistic_module_name_statistic_module_id;

CREATE FUNCTION `func_select_statistic_module_name_statistic_module_id`(
`v_statistic_module_id` int
) RETURNS varchar(50) CHARSET utf8
READS SQL DATA
BEGIN

[...]

RETURN v_name;
END



Was allerdings nach MySQL-Bug 24690 (http://bugs.mysql.com/bug.php?id=24690) nicht wie gewünscht funktioniert und erst in Version 6 gefixt sein wird...

Bin jetzt zu müde um über nen Workaround nachzudenken.
Ginge so in die Richtung Default Collation für utf8 in utf8_unicode_ci ändern statt utf8_general_ci. Oder die Rückgabe der Funktion nach unicode zu convertieren.
Werde da morgen weiter denken, vielleicht hat ja jemand noch ne interessante Idee :-)

MfG
Carsten

Damir
04.06.2009, 07:56:54
Obwohl in der my.cnf die default-collation=utf8_unicode_ci gesetzt ist, findet sich in der Tabelle information_schema.COLLATIONS ein Eintrag bei Default auf utf8_general_ci und alle Tabellen in der Datenbank mysql und information_schema sind auf utf8_unicode_ci gesetzt.


Hmm, ich vermute mal das MySQL schon mit utf8_general_ci kompiliert wurde und daher der Wert so automatisch gestezt ist....

Wegen Deinem Problem - kann es sein, das Du in nachhinein alles auf UTF8 umgestellt hast oder hast du von Grund auf alles auf UTF8 eingestellt und erst dann die Daten eingefügt? Das Problem kommt eigentlich immer dann auf wenn man den "Pfad der Tugend" ;-) verlässt - spricht, man darf die Kette nicht verlassen und muss wirklich alles (von der Verbindung zur DB bis zum auslesen der Tabelle mit UTF8 machen).

Vielleicht würde hier auch http://de2.php.net/manual/de/function.utf8-encode.php und http://de2.php.net/manual/de/function.utf8-decode.php weiter helfen...

Oft reicht es schon aus wenn man einfach alle Daten expotiert, eine komplette neue Tabelle erstellt, die komplett auf UTF8 einstellt und dann die Daten richtig wieder in die DB einfliessen lässt...

Damir

CeBe
04.06.2009, 12:52:37
Hmm, ich vermute mal das MySQL schon mit utf8_general_ci kompiliert wurde und daher der Wert so automatisch gestezt ist....

leider nein:
./configure --with-charset=utf8 --with-collation=utf8_unicode_ci --with-unix-socket-path=/var/run/mysqld/mysqld.sock --with-tcp-port=3306 --with-mysqld-user=mysql --without-bench --without-debug --prefix=/usr/ --sysconfdir=/etc/

Wegen Deinem Problem - kann es sein, das Du in nachhinein alles auf UTF8 umgestellt hast oder hast du von Grund auf alles auf UTF8 eingestellt und erst dann die Daten eingefügt? Das Problem kommt eigentlich immer dann auf wenn man den "Pfad der Tugend" ;-) verlässt - spricht, man darf die Kette nicht verlassen und muss wirklich alles (von der Verbindung zur DB bis zum auslesen der Tabelle mit UTF8 machen).

Alle Felder, alle Tabellen, meine Datenbank (information_schema allerdings nicht), die Verbindung sind alle UTF8, im PHP nutze ich nur die Multi-Byte-String funktionen und die Ausgabe ist ebenfalls UTF8.

Da liegt aber nicht das Problem, habe das ja schon soweit lokalisiert, dass es mit dem o.g. Bug zusammen hängt.

Oft reicht es schon aus wenn man einfach alle Daten expotiert, eine komplette neue Tabelle erstellt, die komplett auf UTF8 einstellt und dann die Daten richtig wieder in die DB einfliessen lässt...
Habe sogar schon nen neuen komplett frischen Server aufgesetzt ;-)

Das Problem ist, dass wenn ich in der Funktion sage:
CHARSET utf8 ohne eine COLLATION anzugeben nimmt er per Default utf8_general_ci, weil das die Standard-Collation für utf8 ist bei MySQL.
Eine COLLATION kann ich, wie im Bug oben (http://bugs.mysql.com/bug.php?id=24690) erklärt ist nicht angeben, da das erst in Version 6 gefixt wird und Version 5.4 sogar noch Beta ist.
Bin nun auf der Suche nach einer Möglichkeit das umzustellen, dass er utf8_unicode_ci als default hat oder noch besser gar kein utf8_general_ci mehr kennt...

MfG
Carsten

CeBe
05.06.2009, 11:40:15
Yeah! Ich hab nen Workaround :-)

Die Lösung heißt CAST (http://dev.mysql.com/doc/refman/5.4/en/charset-convert.html).

CAST(func_my_function(1, 'test') AS CHAR CHARACTER SET utf8) COLLATE utf8_unicode_ci;

3 volle Arbeitstage wegen so nem sch... Bug :-D und es funzt :-)

Da nochmal der Bug: http://bugs.mysql.com/bug.php?id=24690

Damir
05.06.2009, 11:42:32
Kenne ich zur Genüge diese Suche nach etwas ...;-)

Aber ist doch gut das es jetzt klappt und das Du den Fehler selber gefunden hast;-)

Damir