Perl DBI::fetchrow_array() 为 NULL 给出 empty 而不是 undef

Perl DBI::fetchrow_array() gives empty instead of undef for NULL

迁移到新服务器后,在执行 SELECT 查询时,如果请求的列值为 NULL,Perl 的 DBI::fetchrow_array() returns 似乎是一个空字符串:defined() returns 1 和 length() returns 0.

我读到的所有内容都告诉我,我应该从 NULL 中获取 undef,这确实是我的工作方式旧服务器。新服务器有一个 MySQL 数据库的副本,我使用 Export SQLImport SQL Sequel Pro 的功能,一个 MySQL gui,我 运行 在我的 Mac 上。对于这两个数据库,有问题的值在 Sequel Pro 中明确显示为灰色 NULL,如果我 运行 mysql 交互显示为 NULL。例如,请参阅此抄本中的 name

mysql> SELECT * from trials WHERE id = 26069 ;
+-------+----------+-----------+---------+--------+ ...
| id    | language | numTrials | name    | status | ...
+-------+----------+-----------+---------+--------+ ...
| 26069 | en       |         3 | NULL    | Done   | ...
+-------+----------+-----------+---------+--------+ ...
1 row in set (0.00 sec)

我的旧服务器 运行正在使用旧软件包:

这是我的代码 fetchrow_array:

@result = $statementHandle->fetchrow_array ;

for my $value (@result) {
    if (! utf8::is_utf8($value)) {
        utf8::decode($value) ;

        # Log values for debugging the NULL/undef issue:
        my $aValue = $value ;
        my $len = length($aValue) ;
        if (!defined($value)) {
            $aValue = "<unnndefined>" ;
        }
        print {*::STDLOG} info => "daValue l=$len : $daValue\n" ;
    }
}

非常感谢任何可以提出这里可能发生的事情的人!

您的代码会产生警告

Use of uninitialized value in subroutine entry

您对 utf8::decode($value) 的调用试图将 $value 转换为字符串。如果你传递它 undef 那么该值将被视为空字符串(带有伴随的警告)并解码并存储

将所有这些代码包含在条件语句中似乎很奇怪。当然你只是想要

utf8::decode($value) if $value and not utf8::is_utf8($value);

然后其余代码应该独立于字段的编码状态?

更好的是,您应该通过向数据库 [=17= 添加选项 {mysql_enable_utf8mb4 => 1} 来确保 DBI 在进出数据库的过程中自动编码和解码字符串] 称呼。您还需要将 CHARACTER SET utf8mb4 添加到 CREATE TABLECREATE DATABASE 语句中。 (不要使用 CHARACTER SET utf8;它是真正的 UTF-8 的子集,每个字符限制为三个字节。)当然,如果需要,您可以在初始创建后 ALTER TABLE