2014-12-26 31 views
3

我有這個Perl腳本連接到sqlplus數據庫並運行以下命令。如何在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運行第二個命令。我嘗試過很多方面沒有成功。像

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

但它無法連接到sqlplus或寫入輸出文件。我在谷歌和其他論壇搜索,但沒有得到任何解決方案。請幫忙。 :)

+3

我會建議使用[DBI(https://metacpan.org/pod/DBI)和[DBD ::甲骨文(HTTPS: //metacpan.org/pod/DBD::Oracle)而不是調用外部程序來與數據庫進行交互。它更加高效,安全和靈活。 – Schwern

+0

是的......同意你的看法,爲此我浪費了我的兩個寶貴的日子,在我的Sun Solsaris操作系統上安裝DBD :: Oracle時沒有任何成功。我嘗試了一切,最後我不得不退出。:( – Ankur

+0

Check如果有Solaris的XE oracle,就像它自帶的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。它用單引號表示,這意味着沒有任何變量會被內插。你真的試圖運行$SQLPLUS @${basePath}/VoucherQuery4.sql $startdate。你需要雙引號。

但是最好將您的命令和參數作爲數組參考,這樣IPC :: Run將爲您處理shell引用。

下面是一個使用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行...但在prod我會運行它在數百萬行..是IPC ::運行真正更有效的替代反向... – Ankur

+4

@Ankur,如果你是頂級PERFOR後浪漫,DBI是唯一的答案。如果你不能在Solaris上安裝它,請先在Linux上嘗試 - 只是爲了驗證它的工作原理和工作的快速 – mvp

+1

@Ankur IPC :: Run是一種*更安全的*和更有效的反引號替代方法。對於像你這樣的簡單命令,只需將命令的輸出傳送給文件即可,這不是必需的。由於你沒有閱讀輸出,你應該使用'system'。 DBI將比所有這些更有效率。 – Schwern

相關問題