передача значений из одной подпрограммы в другую в Perl - PullRequest
0 голосов
/ 21 октября 2011

Нужна помощь в создании моего Perl-кода. У меня есть части, работающие там, где я могу извлечь результаты одного вызова подпрограммы $cmd->ls("$chkdir"); и получить результат с помощью ключа $dirnm->{path} (например, Directory: '/home/mydir').

Что мне нужно сделать, это передать этот результат ('/ home / dir') другой подпрограмме в качестве входных данных для соединения dbi с помощью оператора sql (sub results_in)

Так, как мне это построить, чтобы я мог передавать значения, вызываемые из одной подпрограммы в другую?

Пример кода:

my $DirResults = $cmd->ls("$chkdir"); #$chkdir is directory passed as argument
for my $dirnm ( @{$DirResults->{directory}} ) {
    print "Directory:  " . $dirnm->{path} . "\n";
}

#
### Database handle
#
my $dbh_oracle = DBI->connect(
      $CFG{oracle_dbi_connect},
      $CFG{db_user},
      $CFG{db_cred},
      {AutoCommit => 0,
       RaiseError => 0,
       PrintError => 0}) or die ("Cannot connect to the database: ".$DBI::errstr."\n");
my $res_in=results_in($dirnm->{path});  #Here for pseudo code
$dbh_oracle->disconnect();       

sub results_in
{
  my $sth= $dbh_oracle->prepare(q{
       INSERT into mydirs
          VALUES (280, '$res_in')}) ||
      die ("Cannot connect to the database: ".$DBI::errstr."\n");
  $sth->execute;
  $sth->finish;
}

Ответы [ 2 ]

6 голосов
/ 21 октября 2011

Ваш звонок правильный.Проблема в том, что $dirnm существует только в цикле, но вы используете его вне цикла.Вам нужно переместить петлю между точкой, где соединение открыто, и точкой, где оно закрыто.

В то же время давайте немного очистим.Вы не хотите prepare более одного раза;это расточительно.Этого можно избежать, используя заполнители.

Заполнители также избавляют вас от необходимости преобразовывать путь в литерал SQL, что вы плохо пытались сделать, добавляя кавычки.Это рецепт для инъекционной ошибки / атаки.

Таким образом, мы в итоге получаем следующее:

my $dbh_oracle = DBI->connect(...);

my $sth = $dbh_oracle->prepare(q{
   INSERT INTO mydirs VALUES (280, ?, DEFAULT, 1700)
});

my $DirResults = $cmd->ls($chkdir);
for my $dirnm (@{ $DirResults->{directory} }) {
    $sth->execute( $dirnm->{path} );
}

$sth->finish();
$dbh_oracle->disconnect();

(Обработка ошибок удалена, чтобы сделать вещи краткими и к сути для этого поста.оставьте его или используйте RaiseError=>1.)

Не было никакого смысла иметь подчиненное устройство (кроме execute), поэтому я не использовал его.Но так как вы специально задали вопрос о дополнительном вызове, ниже показано, как может выглядеть код с дополнительным вызовом:

sub results_in {
   my ($sth, $path) = @_;
   $sth->execute($path);
}

...
my $DirResults = $cmd->ls($chkdir);
for my $dirnm ( @{$DirResults->{directory}} ) {
    results_in($sth, $dirnm->{path});
}
...
1 голос
/ 21 октября 2011

Вы просто забыли получить параметр, используя @_ до results_in()?Например:

sub results_in
{
  my ($dir) = @_;
  my $sth= $dbh_oracle->prepare(qq{
       INSERT into mydirs
          VALUES (280, '$dir', DEFAULT, 1700)}) ||
      die ("Cannot connect to the database: ".$DBI::errstr."\n");
  $sth->execute;
  $sth->finish;
}

Я что-то пропустил?

Обратите внимание, что я также изменил q{ на qq{, чтобы интерполировать $dir (вместо вставки в виде буквенной строки'$dir')

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...