【问题标题】:Can't find my error找不到我的错误
【发布时间】:2015-10-28 10:12:11
【问题描述】:

您好,这里是我正在开发的一个非常大的 perl 程序的一个小片段,但是我相信这个部分是错误的。

my $headd = "test,test1,test2,test3,ect";
my @headers = split(',', $headd);

CONNECT TO DATABASE STUFF THAT WORKS FINE

 my %column_mapping = (
    "GPS ALT" => 'GPS_ALT',
    "GPS DTS" => 'GPS_DTS',
    "GPS FIX" => 'GPS_FIX',
    "GPS HDG" => 'GPS_HDG'
 )

my $sql       = sprintf 'INSERT INTO tablename ( %s ) VALUES ( %s )',
   join( ',', map { $column_mapping{$_} } @$headers ),
   join( ',', ('?') x scalar @$headers );   # note the list around the '?'

由于我对 perl 还很陌生,如果我不得不猜测我会在这里说它

    join( ',', map { $column_mapping{$_} } @$headers ),
    join( ',', ('?') x scalar @$headers );

我认为我的标题或其他内容的数据类型错误,但我不完全确定问题出在哪里,它只是在这些行周围崩溃。

如果你碰巧看到我做错了什么,那就太好了:)

【问题讨论】:

  • 您是否启用了use strict;?如果是这样,您应该得到Global symbol "$headers" requires explicit package name,因为您在顶部声明了数组@headers,但从未声明您尝试在map { ... } @$headers 中使用的数组引用$headers
  • “崩溃”是什么意思?
  • @ThisSuitIsBlackNot 是的,我确实启用了它,我明白了。我不确定如何正确使用地图 {...}@$headers。我是否遗漏了申报行或使用地图错误?
  • @$headers 更改为@headers@headers 是一个数组; @$headers 取消引用您从未声明过的数组 reference $headers
  • 程序员技能中的一个重要工具是准确性。我怀疑您的意思是“未初始化”而不是“已初始化”。请在报告您所看到的内容时更加小心,否则我们将无法为您提供帮助。如果您的map 中有一个未初始化的值,那么我希望$headd 包含在%column_mapping 中不作为键存在的值。

标签: mysql sql arrays perl


【解决方案1】:

您的主要错误是没有将use strictuse warnings 添加到您的Perl 代码的顶部。这些行会发现一些经常潜入 Perl 程序的问题。他们会发现这个问题的。

问题是你声明了一个名为@headers的数组。

my @headers = split(',', $headd);

但是下次你尝试使用它时,你会假设它是一个名为$headers的数组reference

join( ',', map { $column_mapping{$_} } @$headers )

在 Perl 中,$headers@headers 是两个完全不同的变量,它们之间完全没有联系。由于您从未给 $headers 赋值,因此尝试取消引用它 (@$headers) 永远不会顺利。

但是您已经从 cmets 中解决了这个问题。您已经完成了建议的修复(将 @$headers 替换为 @headers),现在您得到了一个不同的错误:

问题是我在连接中有一个初始化值

我假设您的意思是“未初始化”:-)

听起来问题出在我们上面讨论的同一行(现在使用固定语法):

join( ',', map { $column_mapping{$_} } @headers )

那么这里发生了什么?好吧,我们正在有效地将价值观转化为新价值观。对于@headers 中的每个值,我们在%column_mappings 中查找并从哈希中返回相关值。

这怎么会给我们一个未定义的值?那么,如果我们在散列中查找实际上并不存在于散列中的键会发生什么? Perl 给了我们特殊的值“undef”。这会触发您收到的警告。

所以我给你的建议是你仔细检查你在@headers 中得到的值(这将是来自$headd 的值)并确保所有这些可能的值在@ 中都有一个关联的键987654338@.

一种解决方法是在map 中设置一个默认值。可能是这样的:

join( ',', map { $column_mapping{$_} // 'MISSING MAPPING' } @$headers )

这几乎肯定会在以后的某个时候破坏您的数据库交互 - 但至少问题出在哪里是显而易见的!

更新:在有问题的值进入@headers之前消除它们:

my @headers = grep { exists $column_mapping{$_} } split(',', $headd);

您需要将此语句移到 %column_mappings 的定义之后(希望显而易见的原因)。

【讨论】:

  • 你知道是否有一种方法可以代替默认值。在将其制成数组之前从字符串中删除,从数组中删除,或者如果它不在地图中,则不对其进行连接。
猜你喜欢
  • 1970-01-01
  • 2013-11-24
  • 2021-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-19
相关资源
最近更新 更多