LOAD DATA LOCAL INFILE mit UTF-8

LOAD DATA LOCAL INFILE mit UTF-8

am 18.02.2007 13:28:22 von Lothar Kimmeringer

Hallo,

ich versuche hier gerade in eine UTF-8-Tabelle eine Datei
mit UTF-8-Encoding einzuspielen.

Hier erst mal das verwendete Create-Statement:

CREATE TABLE `mytable` (
[...]
`idcl` char(9) NOT NULL,
`identifier` char(6) character set latin1 NOT NULL,
[...]
`preferred_name` char(80) NOT NULL,
`definition` text NOT NULL,
`iso_language_code` char(2) character set latin1 NOT NULL,
`iso_country_code` char(2) character set latin1 NOT NULL,
[...]
PRIMARY KEY (`identifier`,`iso_country_code`,`iso_language_code`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

Versuche ich nun, die Tabelle mit einem

LOAD DATA LOCAL INFILE 'E:\\myfile_zh_utf8.csv'
INTO TABLE mytable FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\r\n' IGNORE 1 LINES

zu fuellen, werden die Daten zwar korrekt gelesen, allerdings
wird der Inhalt nicht mit UTF-8 interpretiert, sondern mit
latin1 (eine Unicode-codierte Datei wird allerdings zwar
gelesen, anschliessend stehen dann aber keine Daten in der
Tabelle). Schaue ich mir die Inhalte z.B. mit HeidiSQL an (den
gleichen Effekt habe ich aber auch mit dem von MySQL mitge-
lieferten QueryBrowser) sehe ich statt z.B. einem ü das von
kaputten Newsreadern allseits bekannte ü. Da dies auch
bei SquirrelSQL so ist, das JDBC nutzt, schliesse ich ein
Problem mit ODBC einfach mal aus.

Suche ich nach "unicode load data local infile mysql" findet
sich auch nicht wirklich Hilfreiches im Web. Natuerlich kann
ich mir ein Javaprogramm schreiben, dass unter Nutzung des
JDBC-Treibers die Daten in die Datenbank pfeffert (da weiss
ich, dass das klappt, da das Hier [TM] schon so im Einsatz ist).

Zum Programmieren bin ich aber momentan zu faul, vor allem
wenn es einen schlauen Parameter gibt, den ich evtl. nur
uebersehen habe.


Gruesse, Lothar
--
Lothar Kimmeringer E-Mail: spamfang@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!

Re: LOAD DATA LOCAL INFILE mit UTF-8

am 18.02.2007 14:44:10 von Christian Kirsch

Lothar Kimmeringer schrieb:
> Hallo,
>
> ich versuche hier gerade in eine UTF-8-Tabelle eine Datei
> mit UTF-8-Encoding einzuspielen.
>
> Hier erst mal das verwendete Create-Statement:
>
> CREATE TABLE `mytable` (
> [...]
> `idcl` char(9) NOT NULL,
> `identifier` char(6) character set latin1 NOT NULL,
> [...]
> `preferred_name` char(80) NOT NULL,
> `definition` text NOT NULL,
> `iso_language_code` char(2) character set latin1 NOT NULL,
> `iso_country_code` char(2) character set latin1 NOT NULL,
> [...]
> PRIMARY KEY (`identifier`,`iso_country_code`,`iso_language_code`)
> ) ENGINE=MyISAM DEFAULT CHARSET=utf8
>
> Versuche ich nun, die Tabelle mit einem
>
> LOAD DATA LOCAL INFILE 'E:\\myfile_zh_utf8.csv'
> INTO TABLE mytable FIELDS TERMINATED BY ';'
> LINES TERMINATED BY '\r\n' IGNORE 1 LINES
>
> zu fuellen, werden die Daten zwar korrekt gelesen, allerdings
> wird der Inhalt nicht mit UTF-8 interpretiert, sondern mit
> latin1 (eine Unicode-codierte Datei wird allerdings zwar
> gelesen, anschliessend stehen dann aber keine Daten in der
> Tabelle). Schaue ich mir die Inhalte z.B. mit HeidiSQL an (den
> gleichen Effekt habe ich aber auch mit dem von MySQL mitge-
> lieferten QueryBrowser) sehe ich statt z.B. einem ü das von
> kaputten Newsreadern allseits bekannte ü.

Das *ist* doch UTF-8. Vielleicht solltest Du Deinem Tool beibringen,
UTF-8 korrekt anzuzeigen?

> Da dies auch
> bei SquirrelSQL so ist, das JDBC nutzt, schliesse ich ein
> Problem mit ODBC einfach mal aus.
>

Ehrlich gesagt: Ich verstehe nicht, wo Du glaubst ein Problem zu haben.
Du möchtest offenbar in bestimmte Felder Deiner Tabelle Daten
reinschreiben, die UTF8-kodiert sind. Dazu benutzt Du LOAD DATA INFILE.
Anschließend guckst Du Dir die Daten mit irgendwas an, was ich nicht
kenne, und das wirft Dir auch wieder UTF-8 aus. Da Du das in einer
Latin-1-Umgebung machst, sieht es "komisch" aus. So what?

Re: LOAD DATA LOCAL INFILE mit UTF-8

am 18.02.2007 15:52:53 von Lothar Kimmeringer

Christian Kirsch wrote:

> > zu fuellen, werden die Daten zwar korrekt gelesen, allerdings
> > wird der Inhalt nicht mit UTF-8 interpretiert, sondern mit
> > latin1 (eine Unicode-codierte Datei wird allerdings zwar
> > gelesen, anschliessend stehen dann aber keine Daten in der
> > Tabelle). Schaue ich mir die Inhalte z.B. mit HeidiSQL an (den
> > gleichen Effekt habe ich aber auch mit dem von MySQL mitge-
> > lieferten QueryBrowser) sehe ich statt z.B. einem ü das von
> > kaputten Newsreadern allseits bekannte ü.
>
> Das *ist* doch UTF-8. Vielleicht solltest Du Deinem Tool beibringen,
> UTF-8 korrekt anzuzeigen?

Ich habe versucht mit drei verschiedenen Tools festzustellen,
ob das Problem beim Tool selbst oder beim LOAD DATA liegt.
Ein Tool ist das offizielle Teil von MySQL, das andere Java-
basiert unter Nutzung des aktuellsten JDBC-Treibers, von dem
ich weiss, dass es UTF-8-Tabellen korrekt ausliesst.

BTW: ü ist eben nicht UTF-8, wenn im "Header" ein Encoding
iso-8859-1 festgelegt wurde (wie z.B. in diesem Posting).
Ein entsprechender Effekt tritt hier zutage. Wuerde ich
mir die Daten der Tabelle per Hex-Editor ansehen, wuerde
dort die Zeichenkette ü stehen, was der Zeichenkette
ü in UTF-8 entspricht.

> Ehrlich gesagt: Ich verstehe nicht, wo Du glaubst ein Problem zu haben.

Verzeihung die direkte Antwort: Wenn Du nicht kapierst, wo das
Problem liegt, warum meinst Du dann eine Antwort geben zu muessen?

> Du möchtest offenbar in bestimmte Felder Deiner Tabelle Daten
> reinschreiben, die UTF8-kodiert sind. Dazu benutzt Du LOAD DATA INFILE.

Soweit hast Du das schon mal verstanden, gut.

> Anschließend guckst Du Dir die Daten mit irgendwas an, was ich nicht
> kenne,

Hier beginnt das Problem auf Deiner Seite:

- HeidiSQL: Nachfolgeprojekt des Opensourceprojekts MySQL-Front
- MySQL Query Browser: http://www.mysql.org/downloads/gui-tools/5.0.html
- SquirrelSQL: http://squirrel-sql.sourceforge.net/

Waehrend die ersten beiden direkt mit dem Server ueber Port 3306
kommunizieren, nutzt SquirrelSQL den von MySQL ausgelieferten
JDBC-Treiber. Letzterer beachtet das Encoding der Datenbank, somit
sollten per UTF-8-kodierte Zeichen sauber dargestellt werden,
da ein resultSet.getString(columnName) den entsprechend kodierten
Text zurueckliefert und man als Nutzer des JDBC-Treibers eben
keine Encoding-Thematik mehr beachten muss.

> und das wirft Dir auch wieder UTF-8 aus. Da Du das in einer
> Latin-1-Umgebung machst, sieht es "komisch" aus. So what?

Eine Javaapplikation (was SquirrelSQL ist), arbeitet nicht in
einer "Latin1-Umgebung", sondern mit Unicode. Es muss also am
"LOAD DATA LOCAL INFILE" liegen, wenn Umlaute nicht sauber
beim Select herauskommen. Und wenn, arbeite ich hier unter einer
cp1252-Umgebung, was nicht latin1 ist.


Gruesse, Lothar
--
Lothar Kimmeringer E-Mail: spamfang@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!

Re: LOAD DATA LOCAL INFILE mit UTF-8

am 18.02.2007 16:20:46 von B.Steinbrink

On Sun, 18 Feb 2007 13:28:22 +0100, Lothar Kimmeringer wrote:

> Hallo,
>
> ich versuche hier gerade in eine UTF-8-Tabelle eine Datei
> mit UTF-8-Encoding einzuspielen.
>
> Hier erst mal das verwendete Create-Statement:
>
> CREATE TABLE `mytable` (
> [...]
> `idcl` char(9) NOT NULL,
> `identifier` char(6) character set latin1 NOT NULL,
> [...]
> `preferred_name` char(80) NOT NULL,
> `definition` text NOT NULL,
> `iso_language_code` char(2) character set latin1 NOT NULL,
> `iso_country_code` char(2) character set latin1 NOT NULL,
> [...]
> PRIMARY KEY (`identifier`,`iso_country_code`,`iso_language_code`)
> ) ENGINE=MyISAM DEFAULT CHARSET=utf8
>
> Versuche ich nun, die Tabelle mit einem
>
> LOAD DATA LOCAL INFILE 'E:\\myfile_zh_utf8.csv'
> INTO TABLE mytable FIELDS TERMINATED BY ';'
> LINES TERMINATED BY '\r\n' IGNORE 1 LINES
>
> zu fuellen, werden die Daten zwar korrekt gelesen, allerdings
> wird der Inhalt nicht mit UTF-8 interpretiert, sondern mit
> latin1 (eine Unicode-codierte Datei wird allerdings zwar
> gelesen, anschliessend stehen dann aber keine Daten in der
> Tabelle). Schaue ich mir die Inhalte z.B. mit HeidiSQL an (den
> gleichen Effekt habe ich aber auch mit dem von MySQL mitge-
> lieferten QueryBrowser) sehe ich statt z.B. einem ü das von
> kaputten Newsreadern allseits bekannte ü. Da dies auch
> bei SquirrelSQL so ist, das JDBC nutzt, schliesse ich ein
> Problem mit ODBC einfach mal aus.

Ein kurzer Blick auf http://dev.mysql.com/doc/refman/5.0/en/load-data.html
verrät, dass MySQL den Dateiinhalt gemäß des Wertes von
character_set_database interpretiert, evtl. steht da bei dir noch ein latin1
Wert drin?

Björn

Re: LOAD DATA LOCAL INFILE mit UTF-8

am 18.02.2007 20:49:32 von Lothar Kimmeringer

Björn Steinbrink wrote:

> Ein kurzer Blick auf http://dev.mysql.com/doc/refman/5.0/en/load-data.html
> verrät, dass MySQL den Dateiinhalt gemäß des Wertes von
> character_set_database interpretiert, evtl. steht da bei dir noch ein latin1
> Wert drin?

Genau das war das Problem (den von Dir genannten Link habe ich
schon gelesen, allerdings war ich so auf "UTF-8" fixiert, dass
mir das mit der Variablen nicht ins Auge sprang).

Da ich den Default des Servers aus verschiedenen Gruenden
nicht aendern will, habe ich das jetzt ueber mysqlimport
geloest:

mysqlimport.exe --local --default-character-set=utf8 \
--lines-terminated-by="\r\n" --ignore-lines=1 \
--fields-terminated-by=";" -u root -p mydb mytable.csv

Danke fuer den Hinweis, die Umlaute und chinesischen Zeichen
(die eigentlich da rein sollen), klappen jetzt so wie erwartet.


Danke und Gruesse, Lothar
--
Lothar Kimmeringer E-Mail: spamfang@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!

Re: LOAD DATA LOCAL INFILE mit UTF-8

am 18.02.2007 21:06:40 von B.Steinbrink

On Sun, 18 Feb 2007 20:49:32 +0100, Lothar Kimmeringer wrote:

> Björn Steinbrink wrote:
>
>> Ein kurzer Blick auf http://dev.mysql.com/doc/refman/5.0/en/load-data.html
>> verrät, dass MySQL den Dateiinhalt gemäß des Wertes von
>> character_set_database interpretiert, evtl. steht da bei dir noch ein latin1
>> Wert drin?
>
> Genau das war das Problem (den von Dir genannten Link habe ich
> schon gelesen, allerdings war ich so auf "UTF-8" fixiert, dass
> mir das mit der Variablen nicht ins Auge sprang).

Sorry, war nicht so harsch gemeint wie's letztlich rüberkam.

> Da ich den Default des Servers aus verschiedenen Gruenden
> nicht aendern will, habe ich das jetzt ueber mysqlimport
> geloest:
>
> mysqlimport.exe --local --default-character-set=utf8 \
> --lines-terminated-by="\r\n" --ignore-lines=1 \
> --fields-terminated-by=";" -u root -p mydb mytable.csv

Evtl. würde auch ein "SET SESSION character_set_server=utf8" reichen. Das
ändert den Wert nur für die aktuelle Verbindung.

HTH
Björn

Re: LOAD DATA LOCAL INFILE mit UTF-8

am 19.02.2007 19:13:40 von Lothar Kimmeringer

Björn Steinbrink wrote:

> On Sun, 18 Feb 2007 20:49:32 +0100, Lothar Kimmeringer wrote:
>
>> Genau das war das Problem (den von Dir genannten Link habe ich
>> schon gelesen, allerdings war ich so auf "UTF-8" fixiert, dass
>> mir das mit der Variablen nicht ins Auge sprang).
>
> Sorry, war nicht so harsch gemeint wie's letztlich rüberkam.

Hab's auch nicht so verstanden. Das ganze war mehr als "Mist,
der Loesung so nah und doch nix gemerkt" gemeint. Mir kann
man gerne eine RTFM um die Ohren hauen, wenn ein Link zum
"M" vorhanden ist. ;-)

>> Da ich den Default des Servers aus verschiedenen Gruenden
>> nicht aendern will, habe ich das jetzt ueber mysqlimport
>> geloest:
>>
>> mysqlimport.exe --local --default-character-set=utf8 \
>> --lines-terminated-by="\r\n" --ignore-lines=1 \
>> --fields-terminated-by=";" -u root -p mydb mytable.csv
>
> Evtl. würde auch ein "SET SESSION character_set_server=utf8" reichen. Das
> ändert den Wert nur für die aktuelle Verbindung.

Nachdem das Dateien sind, die regelmaessig in die Datenbank
muessen, wird das mittelfristig wohl sowieso ein Javaprogramm
oder ein Scripts sein. Und ob ich im Script ein
mysql < importcmds.sql
oder ein
for i in *.csv; do
mysqlimport ... $i
}
schreibe, ist ziemlich egal.


Nochmal danke und Gruesse, Lothar
--
Lothar Kimmeringer E-Mail: spamfang@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!