Perl, Mysql, Umlaute, korrekter Zeichensatz

Perl, Mysql, Umlaute, korrekter Zeichensatz

am 17.11.2005 12:50:54 von design4future

Guten Tag.

Seit Tagen schlage ich mich mit einem dummen Problem rum.

Es existiert ein Perl-Tk Programm welches aus einer Mysql Daten abruft
und sie zum

bearbeiten in verschiedenen Widgets anzeigt. Dann sollen sie wieder
zurückgespeichert

werden.

##########################################

Tk-Programm läuft unter Windows
Mysql 3.23(!) läuft unter Linux

##########################################

Dies funktioniert alles einwandfrei.

Allerdings steht anstelle deutscher Umlaute nur noch "Unsinn" in der
Tabelle.
Die Sonderzeichen/Umlaute wurden nicht richtig konvertiert.
Ich habe die Daten jetzt schon in eine Datei gelogt. Da sehen die Daten
einwandfrei aus!

Ich habe mich jetzt schon probiert mit der Materie zu beschäftigen.
Inwiefern mit Erfolg, das müsst Ihr entscheiden.

Ich muss doch die Daten in "ISO-8859-1" konvertieren, oder?

In welchem Format bekomme ich die Daten zurück von Tk?

Perl verwaltet doch seine Daten in UTF8?

Normalerweise müsste ich doch dann die Daten von UTF8 nach Latin1
konvertieren können und

dann in die Datenbankwegspeichern können. Dann kann er den Query aber
nicht ausführen und

"die"d.
Zum konvertieren habe ich "Encode" verwendet. Ist "Recode" besser?


Ich habe schon etwas von einem Query gehört ("Set NAMES 'UTF8'" oder
so) der die

Datenbankverbindung auf einen speziellen Zeichensatz einstellt. Das
funktioniert doch

aber erst ab Mysql4... Hilft mir das weiter?

In der Datenbank werden eigentlich nicht nur Deutsche Daten gespeichert
sondern auch

Englische, Russische, Türkische etc.
Es sind also vermutlich alle Zeichensätze enthalten.



Wäre nett wenn mir jemand Tipps geben könnte.
Ich bin für jede Antwort sehr dankbar.


Gruß Robert

Re: Perl, Mysql, Umlaute, korrekter Zeichensatz

am 17.11.2005 22:15:24 von Slaven Rezic

"design4future" writes:

> Guten Tag.
>
> Seit Tagen schlage ich mich mit einem dummen Problem rum.
>
> Es existiert ein Perl-Tk Programm welches aus einer Mysql Daten abruft
> und sie zum
>
> bearbeiten in verschiedenen Widgets anzeigt. Dann sollen sie wieder
> zurückgespeichert
>
> werden.
>
> ##########################################
>
> Tk-Programm läuft unter Windows
> Mysql 3.23(!) läuft unter Linux
>
> ##########################################
>
> Dies funktioniert alles einwandfrei.
>
> Allerdings steht anstelle deutscher Umlaute nur noch "Unsinn" in der
> Tabelle.
> Die Sonderzeichen/Umlaute wurden nicht richtig konvertiert.
> Ich habe die Daten jetzt schon in eine Datei gelogt. Da sehen die Daten
> einwandfrei aus!
>
> Ich habe mich jetzt schon probiert mit der Materie zu beschäftigen.
> Inwiefern mit Erfolg, das müsst Ihr entscheiden.
>
> Ich muss doch die Daten in "ISO-8859-1" konvertieren, oder?
>
> In welchem Format bekomme ich die Daten zurück von Tk?
>
> Perl verwaltet doch seine Daten in UTF8?
>
> Normalerweise müsste ich doch dann die Daten von UTF8 nach Latin1
> konvertieren können und
>
> dann in die Datenbankwegspeichern können. Dann kann er den Query aber
> nicht ausführen und
>
> "die"d.
> Zum konvertieren habe ich "Encode" verwendet. Ist "Recode" besser?
>
>
> Ich habe schon etwas von einem Query gehört ("Set NAMES 'UTF8'" oder
> so) der die
>
> Datenbankverbindung auf einen speziellen Zeichensatz einstellt. Das
> funktioniert doch
>
> aber erst ab Mysql4... Hilft mir das weiter?
>
> In der Datenbank werden eigentlich nicht nur Deutsche Daten gespeichert
> sondern auch
>
> Englische, Russische, Türkische etc.
> Es sind also vermutlich alle Zeichensätze enthalten.
>

Das Problem ist, dass viele Perl-Module, die eine XS-Schnittstelle
haben, noch nicht utf-8-tauglich gemacht wurden. DBD::mysql (oder ist
es die Verantwortlichkeit von DBI?) scheint dazu zu gehören. Tk
hingegen ist ein vorbildliches Modul, dass *immer* (d.h. seit Version
804.xxx) Daten mit dem utf-8-Flag liefert. Hier gibt es also ein
Problem.

In diesem Fall muss der Programmierer die Daten, die zum "schlechten"
Modul gehen, von "characters" nach "octets" wandeln. Umgekehrt müssen
die Daten, die vom "schlechten" Modul wieder zurück zu Perl kommen,
wieder von "octets" nach "characters" wandeln. Bei den "octets" kann
man sich dabei das Encoding frei wählen, aber generell sollte man ein
Encoding wählen, dass soviel wie möglich vom Unicode-Bereich
unterstützt (Tk kann theoretisch Zeichen von allen möglichen
Zeichensätzen liefern), also nimmt man typischerweise utf-8.

Im Klartext bedeutet das, dass man in die eine Richtung

$db_input = Encode::encode("utf-8", $tk_output);

verwenden muss und $db_input in die Datenbank kommt. In die andere
Richtung macht man

$tk_input = Encode::decode("utf-8", $db_input);

Ob MySQL-Befehle wie "set names 'utf8'" helfen würden, wage ich zu
bezweifeln, da die DBD::mysql-Dokumentation nichts dergleichen
erwähnt. Meiner Vermutung nach helfen die utf-8-Befehle von MySQL nur
bei MySQL-internen Funktionen, z.B. sie sorgen dafür, dass bei ORDER
BY und SUBSTRING() das besondere utf-8-Encoding beachtet wird.

Hier ist ein kleines vollständiges Skript für Tk und DBD::mysql.

#!perl
# Benötigt eine Tabelle
# create table utf8 (a varchar(255));
# in der Datenbank test
use DBI;
use Tk;
use Encode;

$mw = tkinit;
$mw->Entry(-textvariable => \$input)->pack;
$mw->Label(-textvariable => \$output)->pack;
$mw->Button(-text => "Do DB operation",
-command => sub {
$dbh = DBI->connect("dbi:mysql:test", "test", "", { RaiseError => 1 });
$octets = Encode::encode("utf-8", $input);
$dbh->do("delete from utf8");
$dbh->do("insert into utf8 values(?)", undef, $octets);
$res = $dbh->selectall_arrayref("select * from utf8");
$octets_returned = $res->[0][0];
$output = Encode::decode("utf-8", $octets_returned);
})->pack;
MainLoop;
__END__

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

tksm - Perl/Tk program for searching and replacing in multiple files
http://ptktools.sourceforge.net/#tksm

Re: Perl, Mysql, Umlaute, korrekter Zeichensatz

am 22.11.2005 21:03:00 von design4future

Hallo und vielen Dank erst einmal.

Ich hatte gehofft eine Antwort zu bekommen.
Habe diese Änderung an meinem Programm getestet. Leider ohne Erfolg.
Wenn ich die Daten bevor ich sie in die widgets eintrage umforme in
UTF-8 dann steht in meinen Widgets nur Unsinn.



Beispiel:

anstatt von

Großenhainer Hof

steht dann

Groï¿=BDenhainer Hof

in den Widgets.



Genau dieser Müll steht jetzt auch schon in der Datenbank.
Woran liegt das nur?
Ich verstehe es nicht.

Re: Perl, Mysql, Umlaute, korrekter Zeichensatz

am 22.11.2005 23:27:38 von Slaven Rezic

"design4future" writes:

> Hallo und vielen Dank erst einmal.
>
> Ich hatte gehofft eine Antwort zu bekommen.
> Habe diese Änderung an meinem Programm getestet. Leider ohne Erfolg.
> Wenn ich die Daten bevor ich sie in die widgets eintrage umforme in
> UTF-8 dann steht in meinen Widgets nur Unsinn.
>
>
>
> Beispiel:
>
> anstatt von
>
> Großenhainer Hof
>
> steht dann
>
> Gro�enhainer Hof
>
> in den Widgets.
>
>
>
> Genau dieser Müll steht jetzt auch schon in der Datenbank.
> Woran liegt das nur?
> Ich verstehe es nicht.
>

Zeig mal ein minimales (!) lauffähiges (!) Skript, dann können wir
weiterschauen.

Gruß,
Slaven

--
Slaven Rezic - slaven rezic de

tkrevdiff - graphical display of diffs between revisions (RCS, CVS or SVN)
http://ptktools.sourceforge.net/#tkrevdiff