2011-10-20 14 views
-1

私のperlコードを構築する助けが必要です。私はサブルーチン$cmd->ls("$chkdir");への1回の呼び出しから結果を抽出し、キー$dirnm->{path}(例:ディレクトリ: '/ home/mydir')から結果を得ることができる部分を持っています。私がする必要がどのようなperl内のあるサブルーチンから別のサブルーチンへの値の受け渡し

はなるように、それでは、どのように私はこれを構築します(sub results_in)SQL文を使用して、DBI接続への入力として別のサブルーチンに(「/ホーム/ DIR」)

をその結果を渡していますあるサブルーチンから別のサブルーチンに呼び出された値を渡すことはできますか?

コード例:

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; 
} 
+1

あなたの呼び出しは正しいです。問題は '$ dirnm'はループ内にのみ存在するということです。ループが1回だけ入力されたときに何をしたいのかははっきりしていますが、ループが入力されていないときに何をしたいのですか?ループが複数回入力されたときに何をしたいですか? – ikegami

+0

私はそれが可能なら誰でも見つけられる '$ dirnm'を挿入したいと思います。 '$ dirnm'の結果が0の場合は、すべて一緒に終了します。私は基本的に私がこのテーブルに見つけるすべての結果を入力したいと思います。 – jdamae

答えて

1

あなただけ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; 
} 

私は何かを見逃しましたか?私もqq{よう$dirq{を変更

+0

パス「池上のファイル」に遭遇したらどうなるか考えてみましょう。 – ikegami

6

あなたのコールが正しい(文字列リテラル'$dir'として挿入されている対)補間されます。問題は、$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以外の)サブを持つことに意味がないので、私は1つを使用しませんでした。しかし、あなたがサブ呼び出しについて具体的に尋ねたので、以下はサブ呼び出しでコードがどのように見えるかを示しています。

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

... 
my $DirResults = $cmd->ls($chkdir); 
for my $dirnm (@{$DirResults->{directory}}) { 
    results_in($sth, $dirnm->{path}); 
} 
... 
+0

これを見てくれてありがとう。私は別のサブルーチンを使わずに行っていきますが、参考のためにイラストを追加していただきありがとうございます。 – jdamae

関連する問題