2011-10-28 27 views
5

Próbuję napisać ciągi utf-8 do tabeli MySQL przy użyciu perl/DBI. Z jakiegoś powodu ciąg znaków jest przycinany przy pierwszym znaku spoza ASCII.Łańcuch utf-8 zostaje obcięty w tabeli MySQL przy użyciu Perl/DBI

Na przykład, jeśli mogę skonfigurować poniższej tabeli:

CREATE DATABASE testdb DEFAULT CHARSET=utf8; 
CREATE TABLE testdb.testtable (textval CHAR(30)) DEFAULT CHARSET=utf8; 

a następnie uruchom następujący kod perla:

#!/usr/bin/perl 
use strict; 
use DBI; 
my $dbh = DBI->connect('DBI:mysql:host=localhost;database=testdb', 'testuser', 'somepassword', {mysql_enable_utf8 => 1}) or die $DBI::errstr; 
$dbh->do('SET NAMES utf8'); 
$dbh->do("INSERT INTO testtable (textval) VALUES ('the N\xFCrburgring')"); 

To faktycznie pisze "N". (Kiedy należy pisać „Nürburgring”)

Patrząc w dzienniku zapytań MySQL, widzę to:

271 Query INSERT INTO testtable (textval) VALUES ('the Nürburgring') 

więc ciąg jest osiągnięcie serwer DB nienaruszone.

Gdybym wprowadzić tę samą kwerendę bezpośrednio w konsoli MySQL:

INSERT INTO testtable (textval) VALUES ('the Nürburgring'); 

Cały ciąg jest napisane poprawnie. Masz pojęcie, co robię źle?

+0

Co pisze, jeśli zmienisz '\ xFC' na' ü' w swoim skrypcie? – TLP

+0

Robi dokładnie to samo, jeśli użyję literału ü w kodzie perla. – plasticinsect

Odpowiedz

4

Ustawiłeś atrybut mysql_enable_utf8, więc obiecałeś interfejsowi, że dasz mu ciąg znaków w Perlu. Jest to jednak bufor oktetów w kodowaniu Latin1.

use Devel::Peek qw(Dump); 
Dump "the N\xfcrburgring"; 
# FLAGS = (POK,READONLY,pPOK) 
# PV = 0x208e4f0 "the N\374rburgring"\0 

Poprawka jest prosta. Albo zapisywać znaki dosłowne bez \x ucieczek, użyj utf8 pragmy powiedzieć Perl, że kod źródłowy jest w UTF-8 i zapisać źródło w UTF-8 z edytora ...

use utf8; 
use Devel::Peek qw(Dump); 
Dump "the Nürburgring"; 
# FLAGS = (POK,READONLY,pPOK,UTF8) 
# PV = 0x20999f0 "the N\303\274rburgring"\0 [UTF8 "the N\x{fc}rburgring"] 

... lub dekodowania oktety w ciąg znaków. W większości przypadków nie masz do czynienia z literałami, ale z danymi pochodzącymi z zewnątrz, więc lepiej learn about the whole topic of encoding.

use Encode qw(decode); 
use Devel::Peek qw(Dump); 
Dump decode 'Latin1', "the N\xfcrburgring"; 
# FLAGS = (TEMP,POK,pPOK,UTF8) 
# PV = 0x208f6b0 "the N\303\274rburgring"\0 [UTF8 "the N\x{fc}rburgring"] 
+0

Dziękuję za wyjaśnienie. Myślę, że rozumiem to teraz. Zmieniłem wiersz wstawiania na '$ dbh-> do (dekodowanie ('Latin1'," INSERT INTO testtable (textval) VALUES ('N \ xFCrburgring') "));' i teraz działa idealnie. – plasticinsect

Powiązane problemy