我现在一直在讨论这个问题大约5个小时,我真的很沮丧,需要一些帮助。
我正在编写一个Perl脚本,用于从MySQL表中提取作业,然后执行各种数据库管理任务。当前的任务是“创建数据库”。该脚本成功创建了数据库,但是当我为PHP开发人员生成配置文件时,它就会爆炸。
我认为这是引用和解除引用变量的问题,但我不确定究竟发生了什么。我想在这个函数调用之后,会发生一些事情
$$结果{ '的databaseName'}。这就是我得到结果的方式:$result = $select->fetchrow_hashref()
这是我的函数调用,以及函数实现:
函数调用(第127行):
generateConfig($$result{'databaseName'}, $newPassword, "php");
功能实现:
sub generateConfig {
my($inName) = $_[0];
my($inPass) = $_[1];
my($inExt) = $_[2];
my($goodData) = 1;
my($select) = $dbh->prepare("SELECT id FROM $databasesTableName WHERE name = '$inName'");
my($path) = $documentRoot.$inName."_config.".$inExt;
$select->execute();
if ($select->rows < 1 ) {
$goodData = 0;
}
while ( $result = $select->fetchrow_hashref() )
{
my($insert) = $dbh->do("INSERT INTO $configTableName(databaseId, username, password, path)".
"VALUES('$$result{'id'}', '$inName', '$inPass', '$path')");
}
return 1;
}
错误:
Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 142.
Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 154.
第142行:
$update = $dbh->do("UPDATE ${tablename}
SET ${jobStatus}='${newStatus}'
WHERE id = '$$result{'id'}'");
第154行:
print "Successfully created $$result{'databaseName'}\n";
我认为问题来自函数调用的原因是因为如果我注释掉函数调用,一切都很好!
如果有人能帮我理解发生了什么,那就太棒了。
谢谢,
P.S。如果您发现整个存储密码的安全性问题是数据库中的纯文本,那么在正常工作之后将会解决这个问题。 = P
迪伦
答案 0 :(得分:2)
您不希望存储对fetchrow_hashref返回的$ result的引用,因为每次后续调用都将覆盖该引用。
没关系,你在调用generate_config时没有使用引用,因为你是按值传递数据。
您是否在generate_config和调用函数中使用相同的$ result变量?你应该在generate_config中使用自己的'my $ result'。
while ( my $result = $select->fetchrow_hashref() )
# ^^ #add my
这就是你所包含的当前代码段的所有内容。
一些清理:
您正在使用dbh-&gt; prepare,也可以使用占位符。
sub generateConfig {
my($inName, inPass, $inExt) = @_;
my $goodData = 1;
my $select = $dbh->prepare("SELECT id FROM $databasesTableName WHERE name = ?");
my $insert = $dbh->prepare("
INSERT INTO $configTableName(
databaseID
,username
,password
,path)
VALUES( ?, ?, ?, ?)" );
my $path = $documentRoot . $inName . "_config." . $inExt;
$select->execute( $inName );
if ($select->rows < 1 ) {
$goodData = 0;
}
while ( my $result = $select->fetchrow_hashref() )
{
insert->execute( $result->{id}, $inName, $inPass, $path );
}
return 1;
}
答案 1 :(得分:0)
编辑:阅读评论后
我认为这两个错误都与您使用$$result
有关。如果$result
是fetchrow_hashref
的返回值,例如:
$result = $select->fetchrow_hashref()
那么引用其值的正确方法应该是:
print "Successfully created " . $result{'databaseName'} . "\n";
和
$update = $dbh->do("UPDATE ${tablename}
SET ${jobStatus}='${newStatus}'
WHERE id = '$result{'id'}'");
老答案:
在函数generateConfig
中,您可以使用以下语法传递引用:
generateConfig(\$result{'databaseName'},$newPassword, "php");
($$
用于取消引用字符串; \
为您提供对其应用对象的引用。
然后,在print语句本身,我会尝试:
print "Successfully created $result->{'databaseName'}->{columnName}\n";
实际上,fetchrow_hashref
返回一个哈希(不是字符串)。
这应解决一个问题。
此外,您使用的是名为$dbh
的变量,但未显示其设置位置。它是一个全局变量,以便您可以在generateConfig
中使用它吗?是否在执行generateConfig
时进行了初始化?
答案 2 :(得分:0)
当我从Oracle结果集运行hetchrow_hashref时,这让我很生气。 确定列名始终以大写形式返回。 因此,一旦我开始以大写形式引用colum,问题就消失了: insert-&gt; execute($ result-&gt; {ID},$ inName,$ inPass,$ path);