Perl ссылается на хеш-значения и ссылается на них при передаче в подпрограмму? - PullRequest
5 голосов
/ 08 августа 2011

Я бьюсь над этой проблемой уже около 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

Дилан

Ответы [ 3 ]

2 голосов
/ 08 августа 2011

Вы не хотите хранить ссылку на результат $, возвращаемый fetchrow_hashref, так как каждый последующий вызов будет перезаписывать эту ссылку.

Это нормально, вы не используете ссылку при вызове generate_config, поскольку вы передаете данные по значению.

Используете ли вы одну и ту же переменную $ result в generate_config и в вызывающей функции? Вы должны использовать свой собственный «мой $ результат» в generate_config.

      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;
    

    }

0 голосов
/ 18 июля 2013

Это сводило меня с ума, когда я запускал hetchrow_hashref из набора результатов Oracle. Вычеркнутые имена столбцов всегда возвращаются в верхнем регистре. Поэтому, когда я начал ссылаться на столбец в верхнем регистре, проблема исчезла: insert-> execute ($ result -> {ID}, $ inName, $ inPass, $ path);

0 голосов
/ 08 августа 2011

РЕДАКТИРОВАТЬ: после прочтения вашего комментария

Я думаю, что обе ошибки связаны с использованием $$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?

...