(Perl) 在地图中使用未初始化的值 $_
(Perl) Use of uninitialized value $_ in map
我正在尝试使用以下代码将查询结果导出到 CSV 文件:
while (my $query_result = $query_select->fetchrow_arrayref) {
print $fh join (',', map {s{"}{""}g; "=\"$_\"";} @$query_result), "\n";
}
并收到这些警告:
- 在连接 (.) 或字符串中使用未初始化的值 $_
- 在替换中使用未初始化的值 $_ (s///)
因为有些记录中有NULL值。
如何将代码中的undefined值替换为空字符串?
谢谢。
不要试图破解您自己的版本,使用适当的 CSV 模块,例如 Text::CSV
来做到这一点。例如:
use strict;
use warnings;
use Text::CSV;
my $csv = Text::CSV->new( {
binary => 1,
eol => $/,
} );
...
$csv->print(*STDOUT, $query_result);
为什么不让 mysql 使用 SELECT 处理它.... INTO OUTFILE
这是一个示例(来自 mysql 文档),它以许多程序使用的逗号分隔值 (CSV) 格式生成文件:
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;
有几种方法可以做到这一点,具体取决于您希望何时进行。
1:地图内。
Map 将评估给定块的全部内容,因此如果 $_ 为空,您可以将其设为空字符串。
print $fh join (',', map {$_='' if (!defined $_); s{"}{""}g; "=\"$_\"";} @$query_result), "\n";
2:我将采取的方法是确保从数据库中获取值时不为空。我能想到的每个 RDBMS 都有一个合并函数,该函数 returns 列表中的第一个非空值。
SELECT coalesce(a,''),coalesce(b,''),coalesce(c+d,'')...
将确保您不会得到空值。
say join " , ", map { s{"}{""}g; "\"$_\"" ; }
@{["stuff", undef, "nonsense", undef, "\""]} ;
重现您的错误:
Use of uninitialized value $_ in substitution (s///) at (eval 644) line 10.
Use of uninitialized value $_ in concatenation (.) or string at (eval 644) line 10.
Use of uninitialized value $_ in substitution (s///) at (eval 644) line 10.
Use of uninitialized value $_ in concatenation (.) or string at (eval 644) line 10.
要修复它,您只需使用 map
两次到 "pre-munge" 列表,将 undefs 转换为其他内容:
say join " , ", map { s{"}{""}g; "\"$_\"" ; } (
map { $_="NA" if (not defined $_) ; $_ }
@{["stuff", undef, "nonsense", undef, "\""]} ) ;
输出:
"stuff" , "NA" , "nonsense" , "NA" , """"
有点难看(从 re.pl
剪切和粘贴)但你明白了。
说到 "pre-munging",您的 $query_select->
调用是否可以通过某种方式在查询过程中做到这一点?更改查询可能会避免该级别的问题(e.g. with for (@queryrow) {$_ = 'NA' unless defined};
或其他)。
$=$//'';等同于$=' ' 除非定义 $;
print $fh join (',', map {$_=$_//'';s{"}{""}g; ;"=\"$_\""} @{$query_result}), "\n";
我正在尝试使用以下代码将查询结果导出到 CSV 文件:
while (my $query_result = $query_select->fetchrow_arrayref) {
print $fh join (',', map {s{"}{""}g; "=\"$_\"";} @$query_result), "\n";
}
并收到这些警告:
- 在连接 (.) 或字符串中使用未初始化的值 $_
- 在替换中使用未初始化的值 $_ (s///)
因为有些记录中有NULL值。
如何将代码中的undefined值替换为空字符串?
谢谢。
不要试图破解您自己的版本,使用适当的 CSV 模块,例如 Text::CSV
来做到这一点。例如:
use strict;
use warnings;
use Text::CSV;
my $csv = Text::CSV->new( {
binary => 1,
eol => $/,
} );
...
$csv->print(*STDOUT, $query_result);
为什么不让 mysql 使用 SELECT 处理它.... INTO OUTFILE
这是一个示例(来自 mysql 文档),它以许多程序使用的逗号分隔值 (CSV) 格式生成文件:
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;
有几种方法可以做到这一点,具体取决于您希望何时进行。
1:地图内。
Map 将评估给定块的全部内容,因此如果 $_ 为空,您可以将其设为空字符串。
print $fh join (',', map {$_='' if (!defined $_); s{"}{""}g; "=\"$_\"";} @$query_result), "\n";
2:我将采取的方法是确保从数据库中获取值时不为空。我能想到的每个 RDBMS 都有一个合并函数,该函数 returns 列表中的第一个非空值。
SELECT coalesce(a,''),coalesce(b,''),coalesce(c+d,'')...
将确保您不会得到空值。
say join " , ", map { s{"}{""}g; "\"$_\"" ; }
@{["stuff", undef, "nonsense", undef, "\""]} ;
重现您的错误:
Use of uninitialized value $_ in substitution (s///) at (eval 644) line 10.
Use of uninitialized value $_ in concatenation (.) or string at (eval 644) line 10.
Use of uninitialized value $_ in substitution (s///) at (eval 644) line 10.
Use of uninitialized value $_ in concatenation (.) or string at (eval 644) line 10.
要修复它,您只需使用 map
两次到 "pre-munge" 列表,将 undefs 转换为其他内容:
say join " , ", map { s{"}{""}g; "\"$_\"" ; } (
map { $_="NA" if (not defined $_) ; $_ }
@{["stuff", undef, "nonsense", undef, "\""]} ) ;
输出:
"stuff" , "NA" , "nonsense" , "NA" , """"
有点难看(从 re.pl
剪切和粘贴)但你明白了。
说到 "pre-munging",您的 $query_select->
调用是否可以通过某种方式在查询过程中做到这一点?更改查询可能会避免该级别的问题(e.g. with for (@queryrow) {$_ = 'NA' unless defined};
或其他)。
$=$//'';等同于$=' ' 除非定义 $;
print $fh join (',', map {$_=$_//'';s{"}{""}g; ;"=\"$_\""} @{$query_result}), "\n";