utf8-Daten in latin1-Tabelle und String-Funktionen

utf8-Daten in latin1-Tabelle und String-Funktionen

am 23.04.2007 20:52:55 von Joscha Feth

Hallo zusammen,

ich habe hier ein Problem, welches ich nicht lösen kann und auch laut
der MySQL-Doku garnicht auftreten sollte?! Ich fürchte es liegt am
Setup, ich bin aber nicht in der Lage dieses zu ändern:

ich habe eine latin1-Tabelle (Collation der Tabelle und Datenbank ist
latin1_swedish_ci) in der utf8-formatierte Daten (!) gespeichert sind.
Ich weiß, seltsam, kann es aber nicht ändern.
Ich benötige das erste Zeichen eines Feldes. Wenn ich nun ein
SUBSTRING(feld, 1, 1) mache, dann bekomme ich bei Sonderzeichen
(Ä,ö,ü, etc.) nur Fragezeichen geliefert (da das zweite Byte fehlt).
Selektiere ich SUBSTRING(feld, 1, 2) bekomme ich meine Sonderzeichen
korrekt, bei allen anderen Daten allerdings die beiden ersten Zeichen.
Ich habe schon sämtliche Kombinationen probiert um den String-
Funktionen mitzuteilen, dass sich in dem Feld trotz latin1-Daten auch
Unicode befindet.
SUBSTRING(CONVERT(title USING utf8) COLLATE utf8_unicode_ci,1,1)
funtioniert aber ebensowenig wie dasselbe mit CAST. Ich bekomme immer
kaputte Zeichen.

Was ich nun mache ist folgendes:
ich selektiere die zwei ersten Bytes/Zeichen, lade das ganze in ein
Array, wandle es mit multibyte-Funktionen in UTF-8 um (ich weiß ja,
dass es Unicode ist), und lösche dann das zweite Zeichen. Der Hack
funktioniert zwar, aber ich hätte das eigentlich lieber auf
Datenbankebene gelöst. Vor allem, da ich das auch sortieren möchte.
Irgendwer eine Idee? Wie gesagt: Tabelle ändern fällt flach, auch wenn
das das richtige Vorgehen wäre.

Vielen Dank!
Joscha

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 23.04.2007 22:18:46 von Michael Ziegler

Hallo,

ich denke die sinnvollste Vorgehensweise wäre es, per SET NAMES UTF8 die
Codierung der Verbindung auf UTF8 einzustellen. MySQL konvertiert dann
die Daten beim Speichern in Latin1 und beim Lesen wieder in UTF8, sodass
dein Clientprogramm weiterhin UTF8 sprechen kann.

Dadurch speichert MySQL die Daten auch wirklich in dem Zeichensatz, mit
dem es dann später arbeiten will, und die String-Funktionen
funktionieren wieder.

Gruß,
Michael

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 24.04.2007 00:12:28 von Axel Schwenke

Joscha Feth wrote:

> ich habe hier ein Problem, welches ich nicht lösen kann und auch laut
> der MySQL-Doku garnicht auftreten sollte?! Ich fürchte es liegt am
> Setup, ich bin aber nicht in der Lage dieses zu ändern:
>
> ich habe eine latin1-Tabelle (Collation der Tabelle und Datenbank ist
> latin1_swedish_ci) in der utf8-formatierte Daten (!) gespeichert sind.

Zwei Fehler.

1. Das Encoding ist Eigenschaft der Spalte. Encoding-Angaben für
Datenbanken bzw. Tabellen sind lediglich Defaults.

2. Wenn du mit MySQL einen Vertrag abschließt, in Spalte X nur latin1
Strings halten zu wollen, dann wird MySQL sich daran halten.
Ich weiß ja nicht, wie du das im realen Leben hältst, aber ein
Vertrag ist ein Vertrag ist ein Vertrag.



> Wie gesagt: Tabelle ändern fällt flach, auch wenn
> das das richtige Vorgehen wäre.

Tja. Keine Arme, keine Kekse!


XL

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 24.04.2007 09:11:14 von Joscha Feth

Hallo Michael,

On 23 Apr., 22:18, Michael Ziegler
wrote:
> ich denke die sinnvollste Vorgehensweise wäre es, per SET NAMES UTF8 die
> Codierung der Verbindung auf UTF8 einzustellen. MySQL konvertiert dann
> die Daten beim Speichern in Latin1 und beim Lesen wieder in UTF8, sodass
> dein Clientprogramm weiterhin UTF8 sprechen kann.

Das ändert leider nichts an den Daten, die bereits in der Tabelle
sind.
Beim Schreiben kann ich den Verbindungszeichensatz nicht umstellen und
beim Lesen hätte ich das Problem doch wieder, oder?
Die String-Funktionen sende ich ja immer gleich und die Daten _in_ der
Tabelle werden vor dem Ausführen der Funktionen ja nicht
konvertiert...

schöne Grüße,
Joscha

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 24.04.2007 09:16:50 von Joscha Feth

Hallo Axel,

On 24 Apr., 00:12, Axel Schwenke wrote:
> Zwei Fehler.
>
> 1. Das Encoding ist Eigenschaft der Spalte. Encoding-Angaben für
> Datenbanken bzw. Tabellen sind lediglich Defaults.
Ja, richtig. Die Spalte ist latin1.


> 2. Wenn du mit MySQL einen Vertrag abschließt, in Spalte X nur latin1
> Strings halten zu wollen, dann wird MySQL sich daran halten.
> Ich weiß ja nicht, wie du das im realen Leben hältst, aber ein
> Vertrag ist ein Vertrag ist ein Vertrag.
Im richtigen Leben schließe ich die Verträge eigentlich immer
selbst ;) Ich hätte einen wunderhübschen utf8-Vertrag geschlossen -
aber wie das eben manchmal so ist kann man sich nicht immer aussuchen
wie die Daten, die man bekommt aussehen...

> > Wie gesagt: Tabelle ändern fällt flach, auch wenn
> > das das richtige Vorgehen wäre.
>
> Tja. Keine Arme, keine Kekse!
Ich hatte schon befürchtet, dass es keine Lösung für ein derart
gestricktes Problem gibt (außer der nachträglichen Konvertierung).

Danke für deine Antwort,
Joscha

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 24.04.2007 09:51:06 von Michael Ziegler

Joscha Feth schrieb:
> Das ändert leider nichts an den Daten, die bereits in der Tabelle
> sind.

Stimmt, aber damit du hier irgendwas gebacken kriegen kannst wirst du
die Daten wohl oder übel konvertieren müssen...

Vielleicht kannst du die Daten dumpen ohne die Codierung auf UTF8
einzustellen. Da die Daten ja bereits UTF8 sind, wirst du damit wohl die
Daten korrekt erhalten. Wenn du dann beim Import die Codierung auf UTF8
stellst und den gleichen Dump wieder einspielst, wird MySQL alles in
Latin1 konvertieren.

Deine jetzige Lösung kannst du jedenfalls knicken. Du musst dafür sorgen
dass in dem Feld auch das drinsteht wovon MySQL ausgeht, denn sonst
_kann_ das nicht funktionieren :-)

Viele Grüße,
Michael

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 24.04.2007 10:22:30 von Joscha Feth

Hallo Michael,

On 24 Apr., 09:51, Michael Ziegler
wrote:
> Deine jetzige Lösung kannst du jedenfalls knicken. Du musst dafür sor=
gen
> dass in dem Feld auch das drinsteht wovon MySQL ausgeht, denn sonst
> _kann_ das nicht funktionieren :-)

Alles klar. Ich hatte gehofft mit CONVERT und/oder CAST etwas
erreichen zu können.

Danke!
Joscha

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 24.04.2007 13:59:49 von Dirk Ohme

On 24 Apr., 10:22, Joscha Feth wrote:
> Alles klar. Ich hatte gehofft mit CONVERT und/oder CAST etwas
> erreichen zu können.

Wenn Du einmal die Datenbasis wieder sauber hast, brauchst Du keine
Klimmzüge und Basteleien mehr veranstalten. Ist Dir das denn nicht
klar geworden? ;-)

Gruß, Dirk

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 25.04.2007 22:00:17 von Joscha Feth

Hallo Dirk,

Dirk Ohme schrieb:
> Wenn Du einmal die Datenbasis wieder sauber hast, brauchst Du keine
> Klimmzüge und Basteleien mehr veranstalten. Ist Dir das denn nicht
> klar geworden? ;-)

Ich habe nur lesenden Zugriff auf die Tabelle. Die INSERTs macht eine
andere namhafte OpenSource-Applikation. Und die hat eben
latin1-Tabellen, fügt da aber Unicode ein. Daran kann ich nichts ändern
außer einen Bugreport zu liefern.

schöne Grüße,
Joscha

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 25.04.2007 22:42:36 von Dominik Echterbruch

Joscha Feth schrieb:
>
> Ich habe nur lesenden Zugriff auf die Tabelle. Die INSERTs macht eine
> andere namhafte OpenSource-Applikation. Und die hat eben
> latin1-Tabellen, fügt da aber Unicode ein. Daran kann ich nichts ändern
> außer einen Bugreport zu liefern.

Hmm... Ich habe so den Verdacht, daß die Applikation überhaupt keine
Kodierung beim Anlegen der Tabellen angibt. Also spräche IMHO nichts
dagegen, die Standard-Kodierung von MySQL auf UTF-8 zu stellen und dann
die Anwendung die Tabellen anlegen zu lassen. Danach hättest du die
gewünschten UTF-8 Tabellen.
Alternativ kannst du natürlich die DB komplett dumpen, die Collation
überall manuell setzen und die DB zurück spielen. An sich sollte da
nichts kaputt gehen dürfen tun...
Einen Versuch in einer Test-DB wäre es allemal wert.

Grüße,
Dominik

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 26.04.2007 13:00:37 von Dirk Ohme

On 25 Apr., 22:00, Joscha Feth wrote:
> Ich habe nur lesenden Zugriff auf die Tabelle. Die INSERTs macht
> eine andere namhafte OpenSource-Applikation.

Na, ist doch prima! Wenn "open source", dann kann man den Fehler ja
beheben ...

Gruß, Dirk

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 26.04.2007 15:35:48 von Joachim Durchholz

Dominik Echterbruch schrieb:
> [...] die Standard-Kodierung von MySQL auf UTF-8 zu stellen und dann
> die Anwendung die Tabellen anlegen zu lassen. Danach hättest du die
> gewünschten UTF-8 Tabellen.
> Alternativ kannst du natürlich die DB komplett dumpen, die Collation
> überall manuell setzen und die DB zurück spielen. An sich sollte da
> nichts kaputt gehen dürfen tun...

Einfacher ist wahrscheinlich ein ALTER-Befehl.
(Der könnte allerdings versuchen, die Daten umzukodieren. Ist also
möglicherweise nur eine Verschlimmbesserung.)

> Einen Versuch in einer Test-DB wäre es allemal wert.

Dito.

Grüße
Jo

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 26.04.2007 15:36:08 von Joachim Durchholz

Dirk Ohme schrieb:
> On 25 Apr., 22:00, Joscha Feth wrote:
>> Ich habe nur lesenden Zugriff auf die Tabelle. Die INSERTs macht
>> eine andere namhafte OpenSource-Applikation.
>
> Na, ist doch prima! Wenn "open source", dann kann man den Fehler ja
> beheben ...

Manchmal ist der Aufwand auch schlicht zu groß...

Re: utf8-Daten in latin1-Tabelle und String-Funktionen

am 26.04.2007 16:26:12 von Axel Schwenke

Joachim Durchholz wrote:
> Dominik Echterbruch schrieb:
>> [...] die Standard-Kodierung von MySQL auf UTF-8 zu stellen und dann
>> die Anwendung die Tabellen anlegen zu lassen. Danach hättest du die
>> gewünschten UTF-8 Tabellen.
>> Alternativ kannst du natürlich die DB komplett dumpen, die Collation
>> überall manuell setzen und die DB zurück spielen. An sich sollte da
>> nichts kaputt gehen dürfen tun...
>
> Einfacher ist wahrscheinlich ein ALTER-Befehl.
> (Der könnte allerdings versuchen, die Daten umzukodieren. Ist also
> möglicherweise nur eine Verschlimmbesserung.)

Korrekt macht man das, indem man erst nach BINARY umwandelt und dann
nach UTF8. Bei der Umwandlung von/nach Binary werden die Daten nicht
konvertiert. Und auch das steht natürlich im Handbuch ;)


XL