需要一些帮助来构建我的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;
}
答案 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'
插入)