2012-10-11 24 views
0

我有一列是我的表的主鍵,它可以具有變音符號或普通文本。無法在perl中使用DBI在mysql中插入變音符號文本的等效純文本

我有這2個值:

Håbo and Habo 

我想在我的表中插入這兩列的值,但我得到的錯誤:

DBD::mysql::st execute failed: Duplicate entry 'Habo' for key 'PRIMARY' 

正如我檢查哈博已經插入和它將兩個值都視爲相同,因此主鍵違規。

我的代碼:

$dbh = DBI->connect($dsn, $user, $pass) 
      or die "Unable to connect: $DBI::errstr\n"; 
$dbh->{'mysql_enable_utf8'}=1; 
$dbh->do('SET NAMES utf8'); 
my $sql = sprintf "INSERT INTO search_term values(%s, %s)", $dbh->quote($search_term), "Data"; 

我的表描述

mysql> desc search_term; 
+---------------+--------------+------+-----+---------+-------+ 
| Field   | Type   | Null | Key | Default | Extra | 
+---------------+--------------+------+-----+---------+-------+ 
| search  | varchar(200) | NO | PRI | NULL |  | 
| site   | varchar(500) | NO |  | NULL |  | 
+---------------+--------------+------+-----+---------+-------+ 

我怎樣才能使MySQL把兩個值不同,並插入呢? 有什麼建議嗎?

+0

您可以顯示創建表或描述輸出。 – FreudianSlip

+0

@FreudianSlip:我做了編輯併發布了我的表的描述 – kailash19

+0

作爲一個方面說明,優先使用引號綁定參數。它更快更安全。也總是在INSERT中指定列,否則您將依賴可能更改的表格順序的細節,並且更難理解。 '$ dbh-> prepare(「INSERT INTO search_term(search,site)VALUES(?,?)」); $ sth->執行($搜索,「數據」);' – Schwern

回答

1

默認情況下,MySQL "helpfully" converts Unicode into their "equivalent" ASCII使用的東西叫做Unicode Collation。像MySQL中的許多「便利」功能一樣,如果它告訴你,這將更加方便。我無法在這些「單詞」周圍放置足夠的「引號」。

幸運的是修復非常簡單,但並不明顯。首先,change the character set of your tables to UTF8所以文本存儲在utf8中。然後change the collation to utf8_bin所以比較將完成。我不是100%肯定的,utf8_bin是100%正確的東西,但它是有效的。

ALTER TABLE search_term CONVERT TO CHARACTER SET utf8; 
ALTER TABLE search_term COLLATE utf8_bin; 

在未來,當你在MySQL創建表時,一定要append CHARACTER SET utf8 to the creation

CREATE TABLE search_term (
    search varchar(200) primary key, 
    site varchar(500) 
) 
CHARACTER SET utf8 
COLLATE  utf8_bin; 

最後,這樣你就不必爲每個表做到這一點,你可以create the database with these defaults already in place

這是good post on the Unicode gotchas in MySQL and their fixes

在Perl方面,一定要use utf8,這樣你傳遞給MySQL的字符串被編碼爲utf8。

最後,根據DBD::mysql manual,您需要在連接時打開UTF8支持,而不是之後。如果它發出警告會很好。

Additionally, turning on this flag tells MySQL that incoming data should be 
treated as UTF-8. This will only take effect if used as part of the call to 
connect(). If you turn the flag on after connecting, you will need to issue 
the command SET NAMES utf8 to get the same effect. 

將您的連接更改爲此。

# I threw in RaiseError because its generally a good idea. 
my $dbh = DBI->connect($dsn, $user, $pass, { mysql_enable_utf8 => 1, RaiseError => 1 }); 
+0

嗨Schwern,改變表後,我仍然得到同樣的錯誤。我截斷表並試圖再次插入,但相同的主鍵違規錯誤。 – kailash19

+0

在您的代碼中更新了我的回答,並解決了另一個問題。讓您的堆棧尊重Unicode是PITA。 – Schwern

+0

我已經使用$ dbh-> do('SET NAMES utf8');,但我仍然嘗試了您的解決方案。 我得到同樣的錯誤。 – kailash19

相關問題