0

我有一列是我的表的主键,它可以有变音符号或普通文本。

我有这两个值:

Håbo and Habo

我想在我的表中插入这两个列值,但出现错误:

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

当我检查 Håbo 已经插入并且它处理两个值相同所以主键违规。

我的代码:

$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 将这两个值视为不同并插入它们?有什么建议么?

4

1 回答 1

1

默认情况下,MySQL使用称为Unicode Collat​​ion的东西“有用地”将 Unicode 转换为“等效”的 ASCII。就像 MySQL 中的许多“便利”功能一样,如果它告诉您,这将更加方便。我不能在这些“词”周围加上足够的“引号”。

幸运的是,修复非常简单,但并不明显。首先,将表的字符集更改为 UTF8,以便将文本存储在 utf8 中。然后将排序规则更改为 utf8_bin以便准确进行比较。我不是 100% 确定 utf8_bin 是 100% 正确的,但它确实有效。

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

以后在 MySQL 中创建表时,一定要追加CHARACTER SET utf8创建

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

最后,因此您不必为每个表都这样做,您可以使用这些默认值创建数据库

这是一篇关于 MySQL 中的 Unicode 陷阱及其修复的好帖子

在 Perl 方面,请务必use utf8将传递给 MySQL 的字符串编码为 utf8。

最后,根据DBD::mysql 手册,连接时需要开启 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 });
于 2012-10-11T10:08:11.440 回答