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 SQL 和 Import 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)
我的旧服务器 运行正在使用旧软件包:
- Perl 5.10.1 与 5.22.1
- DBI 1.634 与 1.636
- DBD::mysql 4.022 与 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);
然后其余代码应该独立于字段的编码状态?
更好的是,您应该通过向数据库 [=17= 添加选项 {mysql_enable_utf8mb4 => 1}
来确保 DBI
在进出数据库的过程中自动编码和解码字符串] 称呼。您还需要将 CHARACTER SET utf8mb4
添加到 CREATE TABLE
或 CREATE DATABASE
语句中。 (不要使用 CHARACTER SET utf8
;它是真正的 UTF-8 的子集,每个字符限制为三个字节。)当然,如果需要,您可以在初始创建后 ALTER TABLE
。
迁移到新服务器后,在执行 SELECT 查询时,如果请求的列值为 NULL,Perl 的 DBI::fetchrow_array()
returns 似乎是一个空字符串:defined()
returns 1 和 length()
returns 0.
我读到的所有内容都告诉我,我应该从 NULL 中获取 undef,这确实是我的工作方式旧服务器。新服务器有一个 MySQL 数据库的副本,我使用 Export SQL 和 Import 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)
我的旧服务器 运行正在使用旧软件包:
- Perl 5.10.1 与 5.22.1
- DBI 1.634 与 1.636
- DBD::mysql 4.022 与 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);
然后其余代码应该独立于字段的编码状态?
更好的是,您应该通过向数据库 [=17= 添加选项 {mysql_enable_utf8mb4 => 1}
来确保 DBI
在进出数据库的过程中自动编码和解码字符串] 称呼。您还需要将 CHARACTER SET utf8mb4
添加到 CREATE TABLE
或 CREATE DATABASE
语句中。 (不要使用 CHARACTER SET utf8
;它是真正的 UTF-8 的子集,每个字符限制为三个字节。)当然,如果需要,您可以在初始创建后 ALTER TABLE
。