5

私はこの問題について約5時間頭を悩ませてきましたが、本当にイライラしていて、助けが必要です。

MySQLテーブルからジョブを引き出してさまざまなデータベース管理タスクを実行するPerlスクリプトを書いています。現在のタスクは「データベースの作成」です。スクリプトはデータベースを正常に作成しますが、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 で独自の「my $result」を使用する必要があります。

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

含まれているコードの現在のスニペットで言えることはそれだけです。

いくつかのクリーンアップ:

  1. generate_config を呼び出すときは、参照ではなく値で渡します。これで問題ありません。
  2. undef 警告が表示されます。これは、'use strict;' で実行していることを意味します。良い!
  3. 関数内でレキシカルな $result を作成します。
  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

編集:あなたのコメントを読んだ後

どちらのエラーも、使用に関係していると思います$$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'}'");

古い答え:

functiongenerateConfigでは、次の構文を使用して参照を渡すことができます。

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

($$文字列への参照を逆参照するために使用されます\。適用先のオブジェクトへの参照を提供します)。

次に、印刷ステートメント自体で、次のことを試します。

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

実際、fetchrow_hashref(文字列ではなく) ハッシュを返します。

これで 1 つの問題が解決するはずです。

さらに、という名前の変数を使用して$dbhいますが、それがどこに設定されているかを示していません。で使用できるようにグローバル変数generateConfigですか?実行時に初期化されていますgenerateConfigか?

于 2011-08-08T19:26:55.477 に答える
0

Oracleの結果セットからhetchrow_hashrefを実行していたとき、これは私を夢中にさせていました。列名は常に大文字で返されることがわかりました。したがって、列を大文字で参照し始めたら、問題はなくなりました。

于 2013-07-18T19:48:40.173 に答える