2014-10-17 69 views
1

我不知道這是否是一個錯誤或我做錯了什麼:每的Perl DBI/MySQL的Unicode的錯誤

open my $fh, "<:encoding(iso-latin1)", $file or die "Failed to open $file: $!"; 

$文件

我讀出的數據絕對是ISO-latin1的。

然後,我有一個MySQL表是

ENGINE=InnoDB AUTO_INCREMENT=53072 DEFAULT CHARSET=latin1 

我檢查連接設置:

$dbh->prepare("show variables"); 

其中給出

character_set_client, latin1 
character_set_connection, latin1 
character_set_database, latin1 
character_set_filesystem, binary 
character_set_results, latin1 
character_set_server, latin1 
character_set_system, utf8 

所以對我來說一切都應該罰款:

  • 表是異LATIN1
  • 數據被異latin1的(應該是現在perl的內部字符格式)
  • 連接信息顯示正確的設置
  • 輸出到STDOUT(終端爲異丙latin1的)正確

但是:表中的數據是普通的utf8(在這種情況下很可能是perl的內部格式)。

我是否錯過了這可能是DBI/DBD :: mysql中的一個錯誤?

回答

1

我的猜測是你是對的,這個數據是Perl的內部字符格式。順序是這樣的。

  • 數據在輸入文件存儲爲Latin-1的字節
  • 數據從輸入文件,並自動轉換爲由於編碼選項的Perl的人物在你open聲明
  • 數據發送到MySQL和Perl字符讀
  • 的MySQL通過獲取UTF8而不是Latin-1的輕微混亂,但賣場也無妨最佳它可以

步驟你缺少的是你的Perl編碼字符回拉丁文-1,然後將它們發送到數據庫。顯而易見的解決方案是在發送給數據庫的每個值上調用encode('iso-885901', $string)。如果有某種自動編碼選項會很好。但我找不到一個。

當然,如果您的數據全部爲Latin-1,那麼您可以考慮忽略任何解碼/編碼問題。它應該都是沒有這種複雜性的工作。

+0

我知道編碼可能會解決這個問題,但不應該perl處理這個自動?我的意思是這裏沒有歧義:Perl知道數據庫需要iso拉丁字節而不是utf8字符。 – tim 2014-10-19 10:31:46

+0

你爲什麼認爲Perl知道? – 2014-10-19 15:51:40