2011-10-20 6 views
-1

필자의 펄 코드 구성에 도움이 필요하다. 서브 루틴 $cmd->ls("$chkdir");에 대한 호출에서 결과를 추출하고 $dirnm->{path} 키 (예 : 디렉토리 : '/ home/mydir')의 결과를 얻을 수있는 부분이 있습니다.하나의 서브 루틴에서 perl 내 다른 서브 루틴으로 값 전달하기

내가해야 할 것은 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; 
} 
+1

호출이 정확합니다. 문제는'$ dirnm'이 루프에만 존재한다는 것입니다. 루프가 한 번만 입력 될 때 수행하려는 작업은 매우 분명하지만 루프를 입력하지 않은 경우 수행 할 작업과 루프를 두 번 이상 입력 할 때 수행 할 작업은 무엇입니까? – 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의 파일'경로가 발견되면 어떻게되는지 생각해보십시오. – ikegami

6

귀하의 전화가 올 (리터럴 문자열 '$dir'으로 삽입되는 대) 보간 될 것입니다. 문제는 $dirnm이 루프에만 있지만 루프 외부에서 사용한다는 것입니다. 연결이 열린 지점과 닫힌 지점 사이에서 루프를 이동해야합니다.

동시에 작은 청소를 해보 죠. prepare 번을 두 번 이상 보내지 않으실 겁니다. 낭비입니다. 자리 표시자를 사용하여이를 피할 수 있습니다.

자리 표시자를 사용하면 경로에서 따옴표를 추가하여 가볍게 시도한 SQL 리터럴로 변환하지 않아도됩니다. 그것은 주사 버그/공격의 방법입니다.

는 그래서 우리는 다음과 같이 끝 : (. 오류 짧고이 게시물에 대한 포인트에 물건을 유지하기 위해 제거 핸들링 수행을 유지하거나 RaiseError=>1를 사용합니다.)

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(); 

것은 정말 있었다 더 이상 하위 (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}); 
} 
... 
+0

감사합니다. 나는 다른 하위 루틴을 부르지 않고 갈 것이다. 그러나 나는 참고 용으로 그림을 추가해 주셔서 감사합니다. – jdamae

관련 문제