6

我正在使用 open/print 使用 sqlplus 执行 SQL 语句,如下所示:

open (PLSQL, "|sqlplus -s $db_url");
print PLSQL <<ENDSQL;
... some SQL statements ...
exit;
ENDSQL
close(PLSQL);

我的问题是如果遇到一些错误,如何捕获执行 sql 语句的退出代码。我认为使用 DBI 应该会好得多,但我更喜欢对上述问题有一个解决方案。非常感谢!

4

3 回答 3

7

close()应该告诉你你想知道的:

如果文件句柄来自管道打开,则如果涉及的其他系统调用之一失败或者如果其程序以非零状态退出,则关闭返回 false。如果唯一的问题是程序以非零值退出,$! 将设置为 0 。关闭管道还会等待在管道上执行的进程退出——以防你想在之后查看管道的输出——并隐式将该命令的退出状态值放入 $? 和 ${^CHILD_ERROR_NATIVE}。

要点是close()任何错误都将返回 false,$!仅在系统调用有错误时设置,$?并将设置为退出状态。有关详细信息,请参阅perlvar中的错误变量。

于 2012-09-04T19:22:08.270 回答
2

sqlplus正如您所说,使用 DBI 模块比进行数据库操作要好得多。该实用程序仅用作命令行便利,不适用于任何主要的数据库操作,并且使用该模块您可以更好地控制处理可能遇到的任何错误,这似乎是您问题的重点

Perl 本身不允许连接到进程的 STDIN 和 STDOUT。为此,您需要使用IPC::Open2CPAN 中的模块。阅读与另一个进程的双向通信中的问题

于 2012-09-04T14:29:55.533 回答
2

我没有看到 SQLPlus 为 SQL 语句返回正确的退出代码,只有连接失败或身份验证失败。

echo "SELECT * FROM NO_EXIST;" | sqlplus64 -S  USER/PASS@my.db/MYAPP ; echo $?
SELECT * FROM NO_EXIST
           *
ERROR at line 1:
ORA-00942: table or view does not exist


0

如果您可以管理它,我强烈推荐一个语言库。我不能,所以将 grep 输出ORA-\d\d\d\d\d\d作为失败的指示。

希望有帮助。

于 2012-09-04T12:31:21.710 回答