数据库
首页 > 数据库> > mysql – Perl DBI :: fetchrow_array()为NULL提供空而不是undef

mysql – Perl DBI :: fetchrow_array()为NULL提供空而不是undef

作者:互联网

迁移到新服务器后,在执行SELECT查询时,如果请求的列值为NULL,则Perl的DBI :: fetchrow_array()返回看似空字符串的内容:defined()返回1,length()返回0.

我读到的所有内容都告诉我,我应该从NULL获取undef,这确实是它在我的旧服务器上工作的方式.新服务器有一个MySQL数据库的副本,我使用Sequel Pro的导出SQL和导入SQL功能进行迁移,这是我在Mac上运行的MySQL gui.对于这两个数据库,有问题的值在Sequel Pro中清楚地表示为灰色NULL,如果我以交互方式运行mysql则为NULL.例如,请参阅此成绩单中的名称:

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

我的旧服务器正在运行旧包:

> Perl 5.10.1 vs. 5.22.1
> DBI 1.634 vs. 1.636
> DBD :: mysql 4.022 vs. 4.033

这是我在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);

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

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

标签:mysql,perl,dbi
来源: https://codeday.me/bug/20190623/1267428.html