在perl中将值从一个子例程传递到另一个子例程

时间:2011-10-20 22:26:26

标签: perl

需要一些帮助来构建我的perl代码。我有部分工作,我能够从一个子程序$cmd->ls("$chkdir");的一个调用中提取结果,并从键$dirnm->{path}获得结果(例如目录:'/ home / mydir')。< / p>

我需要做的是将结果('/ home / dir')传递给另一个子例程作为带有sql语句的dbi连接的输入(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 个答案:

答案 0 :(得分:6)

你的电话是正确的。问题是$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。)

再有一个sub(除了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 :(得分:1)

您是否忘记使用@_results_in()收到参数? E.g:

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'插入)