Data::UUID生成16字节UUID插入MariaDB BINARY(16)字段报错
问题:16字节二进制UUID插入MariaDB BINARY(16)字段提示“Data too long”
我创建了如下数据表:
CREATE TABLE `sessions` ( id BINARY(16) NOT NULL, PRIMARY KEY(id) ) ENGINE=InnoDB;
随后用Perl代码生成16字节二进制UUID插入该字段:
$sql = 'INSERT INTO sessions (id) VALUES(?)'; my $generator = Data::UUID->new; my $session_id = $generator->create(); $result = $dbh->do($sql, undef, $session_id);
根据Data::UUID文档,create()方法生成的是16字节二进制UUID,但插入时MariaDB返回错误:Data too long for column 'id'。明明字段和UUID都是16字节,却报错,怀疑是驱动问题——我用的是"dbi:MariaDB:$dbinst:$dbhost"驱动,而使用mysql驱动的用户没遇到这个问题。
原因分析
问题核心是DBD::MariaDB与DBD::mysql对二进制数据的默认处理逻辑不同:
- DBD::mysql会直接将二进制数据以原始字节流的形式传递给数据库;
- DBD::MariaDB默认会把二进制数据当作字符串处理,若数据中包含UTF-8编码敏感字节,会被自动转码,导致原始16字节数据被扩展为更长的字节序列,超出BINARY(16)的长度限制。
解决方案
方法一:显式指定参数为二进制类型
通过DBI的类型常量,告诉驱动当前参数是二进制数据,避免自动转码:
use DBI qw(:sql_types); $sql = 'INSERT INTO sessions (id) VALUES(?)'; my $generator = Data::UUID->new; my $session_id = $generator->create(); # 绑定参数时指定类型为SQL_BINARY $result = $dbh->do($sql, undef, { value => $session_id, type => SQL_BINARY });
方法二:转成十六进制字符串插入
绕开驱动的二进制处理逻辑,先将二进制UUID转为十六进制字符串,再用MariaDB的UNHEX()函数还原成二进制数据插入:
$sql = 'INSERT INTO sessions (id) VALUES(UNHEX(?))'; my $generator = Data::UUID->new; # 直接生成十六进制格式的UUID字符串 my $session_id_hex = $generator->create_hex(); $result = $dbh->do($sql, undef, $session_id_hex);
内容的提问来源于stack exchange,提问作者user4035
相关产品推荐
相关产品推荐

