基本上,我想使用 Perl
open
建立一个到 sqlplus 的管道,发送查询,然后从查询中获取信息。
当前代码:
open(PIPE, '-|', "sqlplus user/password@server_details");
while (<PIPE>) {
print $_;
}
这允许我跳转到 sqlplus 并运行我的查询。
我无法弄清楚如何让 Perl 发送 sqlplus 查询(因为它始终是相同的查询),一旦完成,如何将信息写回 Perl 脚本中的变量?
PS - 我知道
DBI
...但我想知道如何使用上述方法来做到这一点,尽管它很不优雅:)
对代码进行了一些更改,我现在可以将查询发送到 sqlplus 但它断开连接...并且我不知道如何从中获取结果。
my $squery = "select column from table where rownum <= 10;"
# Open pipe to sqlplus, connect to server...
open(PIPE, '|-', "sqlplus user/password@server_details") or die "I cannot fork: $!";
# Print the query to PIPE?
print PIPE $squery;
是否会从 sqlplus 中获取
STDOUT
然后使用 Perl(父)脚本存储它?
基本上,我想将其存储在一个数组中以便稍后解析。
流程图:
Perl 脚本(父) -> 打开管道进入 sqlplus(子) -> 在管道上打印查询 -> sqlplus 在屏幕上输出结果(STDOUT?) -> 将 STDOUT 读入 Perl 脚本(父)中的数组
编辑:使用此方法将进程分叉到 sqlplus 可能不可行,我will必须使用 DBI。就等着看有没有人回答...
忘掉屏幕抓取吧,Perl 有一个完美的数据库接口。
我想你可能想要IPC::Run。您将使用
start
函数来让事情顺利进行:
my $h = start \@cat, \$in, \$out;
您可以将查询分配给
$input
变量并泵送,直到在 $output
变量中获得预期输出。
$in = "first input\n";
## Now do I/O. start() does no I/O.
pump $h while length $in; ## Wait for all input to go
## Now do some more I/O.
$in = "second input\n";
pump $h until $out =~ /second input/;
## Clean up
finish $h or die "cat returned $?";
此示例是从 CPAN 页面盗取的,如果您想要更多示例,您应该访问该页面。
如果您的查询是静态的,请考虑将其移动到自己的文件中,并让
sqlplus
加载并执行它。
open(my $pipe, '-|', 'sqlplus', 'user/password@server_details', '@/path/to/sql-lib/your-query.sql', 'query_param_1', 'query_param_2') or die $!;
while (<$pipe>) {
print $_;
}
如果您在 UNIX 中执行此操作,则很容易。我还没有找到在 Windows 中执行此操作的好方法。下面的 $result 变量将包含查询的输出。我使用字段分隔符,因此之后很容易解析:
$结果 =
$oracle_home/bin/sqlplus -S "/nolog"<<EOF1 connect system/PASSWORD\@INSTNACE set heading off; set linesize 300; set feedback off; set pagesize 0; select username || '+---+' || created || '+---+' || profile || '+---+' from dba_users order by username; exit EOF1
;
打印$结果。 ” ”;