5

我已经在这个问题上纠结了大约 5 个小时,我真的很沮丧,需要一些帮助。

我正在编写一个 Perl 脚本,它从 MySQL 表中提取作业,然后执行各种数据库管理任务。当前任务是“创建数据库”。该脚本成功地创建了数据库,但是当我为 PHP 开发人员生成配置文件时,它就崩溃了。

我认为这是引用和取消引用变量的问题,但我不太确定到底发生了什么。我认为在这个函数调用之后,$$result{'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";

我认为问题出在函数调用的原因是因为如果我注释掉函数调用,一切都会很好!

如果有人可以帮助我了解发生了什么,那就太好了。

谢谢,

ps 如果您发现将整个密码以纯文本形式存储在数据库中存在安全问题,则在正常工作后将得到解决。=P

迪伦

4

3 回答 3

2

您不想存储对从 fetchrow_hashref 返回的 $result 的引用,因为每个后续调用都会覆盖该引用。

没关系,当您调用 generate_config 时,您没有使用引用,因为您是按值传递数据。

您是否在 generate_config 和调用函数中使用相同的 $result 变量?您应该在 generate_config 中使用您自己的“我的 $result”。

      while ( my $result = $select->fetchrow_hashref() )
      #       ^^  #add my

这就是您包含的当前代码片段可以说的全部内容。

一些清理:

  1. 调用 generate_config 时,您是按值传递,而不是按引用传递。这可以。
  2. 您收到 undef 警告,这意味着您正在使用“use strict;”运行。好的!
  3. 在函数中创建词法 $result,通过 my.
  4. 虽然 $$hashr{key} 是有效代码,但 $hashr->{key} 是首选。
  5. 您正在使用 dbh->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;
    

    }

于 2011-08-08T19:56:10.510 回答
0

编辑:阅读您的评论后

我认为这两个错误都与您的 using 有关$$result。If$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'}'");

旧答案:

在 functiongenerateConfig中,您可以使用以下语法传递引用:

generateConfig(\$result{'databaseName'},$newPassword, "php");

($$用于取消引用对字符串的引用;\为您提供对其应用的对象的引用)。

然后,在打印语句本身中,我会尝试:

 print "Successfully created $result->{'databaseName'}->{columnName}\n";

实际上,fetchrow_hashref返回一个哈希(不是字符串)。

这应该可以解决一个问题。

此外,您正在使用名为的变量,$dbh但您没有显示它的设置位置。它是一个全局变量,以便您可以在其中使用它generateConfig吗?执行时是否已初始化generateConfig

于 2011-08-08T19:26:55.477 回答
0

当我从 Oracle 结果集运行 hetchrow_hashref 时,这让我发疯了。原来的列名总是以大写形式返回。因此,一旦我开始以大写形式引用列,问题就消失了: insert->execute( $result->{ID}, $inName, $inPass, $path );

于 2013-07-18T19:48:40.173 回答