我有许多可能需要几分钟才能运行的 pl/sql 程序。在开发它们时,我添加了一些打印语句来帮助调试并提供一些反馈和进度指示器。最初,我在小型测试集上运行这些,输出几乎是瞬时的。现在我正在使用需要几分钟才能运行的大型测试集进行测试,我发现打印到控制台不再合适,因为在程序结束之前什么都不会打印。我习惯于在不缓冲其输出并立即打印它的环境中工作,并且添加简单的打印语句以进行简单的调试和诊断是很常见的。
在 pl/sql 中是否可以立即打印输出(不缓冲)?如果不是,人们推荐什么替代方案来获得类似的结果?
我有许多可能需要几分钟才能运行的 pl/sql 程序。在开发它们时,我添加了一些打印语句来帮助调试并提供一些反馈和进度指示器。最初,我在小型测试集上运行这些,输出几乎是瞬时的。现在我正在使用需要几分钟才能运行的大型测试集进行测试,我发现打印到控制台不再合适,因为在程序结束之前什么都不会打印。我习惯于在不缓冲其输出并立即打印它的环境中工作,并且添加简单的打印语句以进行简单的调试和诊断是很常见的。
在 pl/sql 中是否可以立即打印输出(不缓冲)?如果不是,人们推荐什么替代方案来获得类似的结果?
您可以有一个使用自治事务将消息写入表的过程,例如:
procedure log (p_message)
is
pragma autonomous_transaction;
begin
insert into message_log (user, datetime, message)
values (user, sysdate, p_message);
commit;
end;
然后从另一个 Oracle 会话监视该表。
我们有一个小技巧。
你可以使用 DBMS_APPLICATION_INFO.set_client_info(" some information here"); 创建一些变量并替换“”中的字符串。
并使用 select client_info from v$session 来监控进度。
为此,我一直在使用 dbms_pipe。将消息发送到命名管道并从另一个会话中读取它们。当写入和读取进程可能连接到不同的节点时,此方法在 RAC 环境中可能不起作用。
或者,您可以使用在其自己的会话中使用“pragma automatic_transaction”运行的过程将消息插入表中。您可以从另一个会话中查询这些消息
编辑:我看到我的第二个选项已经被提及。
一般有两种选择:
如果您没有对数据库主机的操作系统访问权限,您仍然可以写入 dbhost 文件系统并将 Oracle 外部定义的表绑定到该文件,以便可以使用 SELECT 查询它。
这可能取决于您的客户端工具。我有一段时间没有使用 SQL*Plus,但是当我在 PL/SQL Developer 中调试程序时,我打开一个命令窗口并发出一个SET SERVEROUTPUT ON命令。然后,当我执行该过程时,打印的任何内容都会DBMS_OUTPUT.PUT_LINE立即显示出来。
编辑:你是对的,我想我只是看到大量输出或其他东西。无论如何,我在网上做了一些搜索并遇到了这个log4plsql - 可能有用。
另一种方法是使用返回日志信息的流水线函数。请参阅此处的示例:http ://berxblog.blogspot.com/2009/01/pipelined-function-vs-dbmsoutput.html当您使用流水线函数时,您不必使用另一个 SQLPLUS/Toad/sql 开发人员等... 会议。
您可以在 PL/SQL Developer 中使用 DBMS Pipe 和 Pipe Viewer 来异步捕获所有放入管道的信息。
小心只有在有人阅读时才将内容放入管道中。否则,当管道已满时,您的调用将失败。
还有使用事件的可能性,PL/SQL Developer 也有一个事件监视器。并且文档应该提供一个如何做到这一点的例子。
另一种选择是让您的 PL/SQL 调用一个过程来发送一封电子邮件,其中包含日志消息。这要求您的数据库具有电子邮件发送功能,可以使用 UTL_SMTP 添加。