Perl/DBI selectrow\u数组范围混淆

Perl/DBI selectrow\u数组范围混淆,perl,dbi,Perl,Dbi,所以,我有一个文件列表,我正在检查一个数据库表,看看是否存在条目,并提取id和目标文件名。如果没有,则插入一个条目并重新填充条目注释id是自动递增的,因此无论我是否需要进行第二次查询 问题是,当我在插入后重新拉入查询时,它将进入的变量是词法的,我认为这是正确的措辞,一旦我离开if的范围!如果已定义块,它将丢失其值 #lookup file db entry my ($fileId, $destFilename) = $dbh->selectrow_array("select fileId,

所以,我有一个文件列表,我正在检查一个数据库表,看看是否存在条目,并提取id和目标文件名。如果没有,则插入一个条目并重新填充条目注释id是自动递增的,因此无论我是否需要进行第二次查询

问题是,当我在插入后重新拉入查询时,它将进入的变量是词法的,我认为这是正确的措辞,一旦我离开if的范围!如果已定义块,它将丢失其值

#lookup file db entry
my ($fileId, $destFilename) = $dbh->selectrow_array("select fileId, destFilename from myTable where sourceFilename = '$file'");
if (! defined $fileId) {
    # calculate out what the destination filename should be here..
    # add missing entry into table
    ($fileId, $destFilename) = $dbh->selectrow_array("select fileId, destFilename from myTable where sourceFilename = '$file'");
    print Dumper $destFilename;
}
print Dumper $destFilename;
这将导致:

$VAR1 = "correctfilenamehere"
$VAR1 = undef
在通过selectrow\u数组调用分配变量之前,我尝试过定义变量。我已经尝试将上述变量从我的更改为我们的。我不明白它为什么这么做


还要注意的是,这段代码位于另一个块中,因此这些变量已经是该范围的词法变量。我原以为它们可以在子块中使用,但据我所知,它并不是这样工作的。

发现了问题,一些代码正在生成同名的词汇变量,我没有注意到,因此父$destFilename被替换为本地变量。

您发布的代码没有显示您描述的行为

$perl-e' 严格使用; 使用警告; 使用数据::转储程序qw转储程序; 子f{$0]-4,abc:} 我的$fileId,$destFilename=f0; 如果定义的$fileId{ $fileId,$destFilename=f1; 打印转储文件名; } 打印转储文件名; ' $VAR1='abc'; $VAR1='abc'; 如果引入一个同名的新变量,则可以得到所描述的bahaviour

$perl-e' 严格使用; 使用警告; 使用数据::转储程序qw转储程序; 子f{$0]-4,abc:} 我的$fileId,$destFilename=f0; 如果定义的$fileId{ 我的$fileId,$destFilename=f1; 打印转储文件名; } 打印转储文件名; ' $VAR1='abc'; $VAR1=未定义;
这不是作用域的工作方式;您编写的代码不会执行此操作。还有一些事情正在发生。请注意,$file参数应该作为参数绑定,而不是插入字符串,这是$dbh->selectrow\u Arrays从myTable中选择fileId,destFilename,其中sourceFilename=?,undf,$file;至于绑定,如果它涉及来自文件系统中文件名以外的任何输入,我完全同意。但是,在受限环境中,仅使用文件系统中的文件名作为输入时,这应该是相当安全的。在所有情况下,绑定参数都是最简单和最好的方法。遗憾的是,在嵌套范围内发生这种掩蔽时,不可能自动检测到,因为这是一种完全合理但可能令人困惑的编码实践。如果您在同一范围内屏蔽一个词法,则会有一个警告。@Grinnz,如果在嵌套范围内发生这种屏蔽时无法自动检测到,我相信perlcritic对此有一个规则。我希望使用警告;那就足够了。您希望在同一作用域中使用两个名称相同的变量的频率是多少。@ikegami我的意思是,不可能知道这是否是有意的。这是罕见的,这确实是,但它happens@Grinnz,我从来没见过。如果我做了,我会说你疯了吗?使用不同的名称!如果一个是顶级的,而另一个是子级的,这可能会因为重构而发生。但是潜艇里有两个同名的变量?这很糟糕,应该发出警告。