Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 如何在perl脚本中使用IPC::Run模块_Oracle_Perl_Solaris_Sqlplus - Fatal编程技术网

Oracle 如何在perl脚本中使用IPC::Run模块

Oracle 如何在perl脚本中使用IPC::Run模块,oracle,perl,solaris,sqlplus,Oracle,Perl,Solaris,Sqlplus,我有一个Perl脚本,它连接到sqlplus数据库并运行下面的命令 my $SQLPLUS='/opt/oracle/product/11g/db_1/bin/sqlplus -S system/coolman7@vsdb'; `$SQLPLUS \@${basePath}/VoucherQuery1.sql $startdate> ${basePath}/QueryResult1.txt`; 现在我尝试通过IPC::run运行第二个命令。我试过很多方法,但都没有成功。像 open (W

我有一个Perl脚本,它连接到sqlplus数据库并运行下面的命令

my $SQLPLUS='/opt/oracle/product/11g/db_1/bin/sqlplus -S system/coolman7@vsdb';
`$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或写入输出文件。我在谷歌和其他论坛上搜索过,但没有找到任何解决方案。请帮忙。:)

一般来说,使用词法文件句柄会使生活更轻松。它们不是全局的,当它们超出范围时会自动关闭

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: $!";
或者你可以用它来帮你

use autodie;
open (my $wfh1, ">", "${basePath}/QueryResult4.txt");
但是您根本不需要手动打开该文件,如果您向它传递一个文件名,IPC::Run将为您执行此操作

下一个问题是传递给
run
的内容。它在单引号中,这意味着所有变量都不会被插值。实际上,您正在尝试运行
$SQLPLUS@${basePath}/VoucherQuery4.sql$startdate
。你需要双引号

但是最好将命令和参数作为数组引用传递,这样IPC::Run将为您处理shell引用

下面是一个使用
cat
读取文件、添加行号并将结果输出到文件的简单示例

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

我建议使用and而不是调用外部程序来与数据库交互。它更加高效、安全和灵活。是的。。。我同意你的观点,为此我浪费了宝贵的两天时间在我的Sun Solsaris OS上安装DBD::Oracle,但没有成功。。我尝试了一切,最后我不得不放弃(检查是否有适用于Solaris的XE oracle,因为它自带的perl和DBD::oracle是现成的。@Ankur DBD::oracle可能是安装过程中的一个难题。试着将您在安装时遇到的问题作为另一个问题发布出来?从长远来看,这将为您省去很多麻烦。您好。非常感谢您的解释。我非常感谢。。我现在能够应用你的解决方案,但我想知道这个run命令比backticks方法花费的时间更长。。目前我在大约有10行的测试数据库上运行它…但在prod中,我将在数百万行上运行它。。IPC::run真的是backticks更有效的替代方法吗???@Ankur,如果你追求最高性能,DBI是相当不错的这是唯一的答案。如果你不能在Solaris上安装它,请先在Linux上试用——只是为了验证它是否能正常工作fast@AnkurRun是反勾选的一种更安全、更具特色的替代方法。对于像您这样的简单命令,只需将命令的输出管道化到一个文件,这是不必要的。而且因为您没有读取输出,您应该使用
系统
。DBI将比所有这些效率都高。感谢您的回答。我最初是在寻找DBI。但在solaris机器中安装DBD::Oracle时,我遇到了无法计数的问题。因此,我不得不采用替代解决方案。。
my $SQLPLUS_EXE = '/opt/oracle/product/11g/db_1/bin/sqlplus';
my $SQLPLUS_DB  = 'system/coolman7@vsdb';
my @SQLPLUS_CMD = ($SQLPLUS_EXE, '-S', $SQLPLUS_DB);

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