2014-12-26 2 views
3

sqlplus 데이터베이스에 연결하고 아래 명령을 실행하는이 Perl 스크립트가 있습니다.Perl 스크립트에서 IPC :: Run 모듈을 사용하는 방법

my $SQLPLUS='/opt/oracle/product/11g/db_1/bin/sqlplus -S system/[email protected]'; 
`$SQLPLUS \@${basePath}/VoucherQuery1.sql $startdate> ${basePath}/QueryResult1.txt`; 

이제 IPC :: Run을 통해 두 번째 명령을 실행하려고합니다. 나는 성공하지 못한 채 여러면에서 노력해 왔습니다. like

open (WFH1, ">", "${basePath}/QueryResult4.txt"); 
run('$SQLPLUS \@${basePath}/VoucherQuery4.sql $startdate', '>', \\WFH1); 
close(WH1); 

하지만, sqlplus에 연결하거나 출력 파일에 쓸 수 없습니다. Google 및 다른 포럼에서 검색했지만 해결책이 없습니다. 도와주세요. :)

+3

나는 것 [DBI (https://metacpan.org/pod/DBI)와 [DBD :: 오라클] (https를 사용하는 것이 좋습니다 : //metacpan.org/pod/DBD::Oracle). 외부 프로그램을 호출하여 데이터베이스와 상호 작용할 필요가 없습니다. 훨씬 더 효율적이고 안전하며 유연합니다. – Schwern

+0

예 ... 당신과 동의합니다. 그런 이유로 나는 성공하지 못한 채 Sun Solsaris OS에 DBD :: Oracle을 설치하는 데 소중한 두 시간을 낭비했습니다. 모든 것을 시도 했으므로 결국에는 종료해야했습니다. : – Ankur

+0

Check 솔라리스 용 XE 오라클이 있다면 자체 perl과 DBD :: Oracle을 그대로 사용할 수 있습니다. –

답변

3

어휘 파일 핸들을 사용하면 일반적으로 훨씬 쉬워집니다. 그것들은 전역 적이 지 않으며 범위를 벗어나면 자동으로 닫힙니다.

open (my $wfh1, ">", "${basePath}/QueryResult4.txt"); 

전체 문제는 open이 실패했기 때문에 성공했는지 확인할 필요가 없습니다. 이것을 두 가지 방법으로 할 수 있습니다. 첫 번째는 ... 손으로

my $query_result_file = "${basePath}/QueryResult4.txt"; 
open (my $wfh1, ">", $query_result_file) 
    or die "Couldn't open $query_result_file for writing: $!"; 

그것을 할 것입니다 또는 당신은 당신을 위해 그것을 할 autodie를 사용할 수 있습니다.

use autodie; 
open (my $wfh1, ">", "${basePath}/QueryResult4.txt"); 

파일을 수동으로 열 필요는 없지만 IPC :: Run은 파일 이름을 전달하면이를 수행합니다.

다음 문제는 run에 전달하는 것입니다. 작은 따옴표 안에 있습니다. 즉, 어떤 변수도 보간되지 않습니다. 문자 그대로 $SQLPLUS @${basePath}/VoucherQuery4.sql $startdate을 (를) 실행하려고합니다. 큰 따옴표가 필요합니다.

그러나 명령과 인수를 배열 ref로 전달하는 것이 더 좋습니다. IPC :: Run이 쉘 인용을 처리합니다.

다음은 cat을 사용하여 파일을 읽는 간단한 예입니다. 줄 번호를 추가하고 그 결과를 파일로 출력합니다. 모두 함께 퍼팅

use IPC::Run qw(run); 
run ["cat", "-n"], "<", "/etc/passwd", ">", "test.out"; 

...

my $SQLPLUS_EXE = '/opt/oracle/product/11g/db_1/bin/sqlplus'; 
my $SQLPLUS_DB = 'system/[email protected]'; 
my @SQLPLUS_CMD = ($SQLPLUS_EXE, '-S', $SQLPLUS_DB); 

run [@SQLPLUS_CMD, "\@${basePath}/VoucherQuery4.sql", $startdate], 
    ">", "${basePath}/QueryResult4.txt"; 
+0

안녕하세요. 설명에 많은 감사드립니다. 정말 고맙습니다. 지금은 솔루션을 적용 할 수 있지만이 실행 명령이 더 오래 걸리는지 궁금합니다. 시간은 방법을 역행 .. 현재 나는 약 10 행을 가지고 테스트 데이터베이스에서 실행하고 ...하지만 찌르다 내가 수백만 행에 그것을 실행합니다 .. IPC가 : :: 정말 더 효율적인 대안을 실행 backticks ?? – Ankur

+4

@Ankur, 당신이 top perfo 후에 있다면 rmance, DBI는 거의 유일한 대답입니다. 솔라리스에 설치할 수 없다면 Linux에서 먼저 시도해보십시오 - 작동하고 빠르게 작동하는지 확인하십시오. – mvp

+1

@Ankur IPC :: Run은 backticks보다 안전하고 기능이 뛰어난 대안입니다.명령의 출력을 파일로 파이프하는 것만 큼 단순한 명령의 경우에는 필요하지 않습니다. 그리고 출력을 읽지 않으므로'system'을 사용해야합니다. DBI는 모든 것보다 훨씬 효율적입니다. – Schwern