21

我有许多可能需要几分钟才能运行的 pl/sql 程序。在开发它们时,我添加了一些打印语句来帮助调试并提供一些反馈和进度指示器。最初,我在小型测试集上运行这些,输出几乎是瞬时的。现在我正在使用需要几分钟才能运行的大型测试集进行测试,我发现打印到控制台不再合适,因为在程序结束之前什么都不会打印。我习惯于在不缓冲其输出并立即打印它的环境中工作,并且添加简单的打印语句以进行简单的调试和诊断是很常见的。

在 pl/sql 中是否可以立即打印输出(不缓冲)?如果不是,人们推荐什么替代方案来获得类似的结果?

4

8 回答 8

18

您可以有一个使用自治事务将消息写入表的过程,例如:

procedure log (p_message)
is
    pragma autonomous_transaction;
begin
    insert into message_log (user, datetime, message)
    values (user, sysdate, p_message);
    commit;
end;

然后从另一个 Oracle 会话监视该表。

于 2009-11-13T15:14:43.573 回答
9

我们有一个小技巧。

你可以使用 DBMS_APPLICATION_INFO.set_client_info(" some information here"); 创建一些变量并替换“”中的字符串。

并使用 select client_info from v$session 来监控进度。

于 2009-11-13T15:11:11.403 回答
2

为此,我一直在使用 dbms_pipe。将消息发送到命名管道并从另一个会话中读取它们。当写入和读取进程可能连接到不同的节点时,此方法在 RAC 环境中可能不起作用。

或者,您可以使用在其自己的会话中使用“pragma automatic_transaction”运行的过程将消息插入表中。您可以从另一个会话中查询这些消息

编辑:我看到我的第二个选项已经被提及。

于 2009-11-16T14:33:21.940 回答
1

一般有两种选择:

  • 将输出发送到 Oracle 表(或临时表)
  • 使用 UTL_FILE 写入(数据库主机)文件系统

如果您没有对数据库主机的操作系统访问权限,您仍然可以写入 dbhost 文件系统并将 Oracle 外部定义的表绑定到该文件,以便可以使用 SELECT 查询它。

于 2009-11-13T15:12:17.797 回答
1

这可能取决于您的客户端工具。我有一段时间没有使用 SQL*Plus,但是当我在 PL/SQL Developer 中调试程序时,我打开一个命令窗口并发出一个SET SERVEROUTPUT ON命令。然后,当我执行该过程时,打印的任何内容都会DBMS_OUTPUT.PUT_LINE立即显示出来。

编辑:你是对的,我想我只是看到大量输出或其他东西。无论如何,我在网上做了一些搜索并遇到了这个log4plsql - 可能有用。

于 2009-11-13T15:51:30.993 回答
1

另一种方法是使用返回日志信息的流水线函数。请参阅此处的示例:http ://berxblog.blogspot.com/2009/01/pipelined-function-vs-dbmsoutput.html当您使用流水线函数时,您不必使用另一个 SQLPLUS/Toad/sql 开发人员等... 会议。

于 2009-11-13T18:43:15.183 回答
1

您可以在 PL/SQL Developer 中使用 DBMS Pipe 和 Pipe Viewer 来异步捕获所有放入管道的信息。

小心只有在有人阅读时才将内容放入管道中。否则,当管道已满时,您的调用将失败。

还有使用事件的可能性,PL/SQL Developer 也有一个事件监视器。并且文档应该提供一个如何做到这一点的例子。

于 2009-11-16T14:38:36.127 回答
0

另一种选择是让您的 PL/SQL 调用一个过程来发送一封电子邮件,其中包含日志消息。这要求您的数据库具有电子邮件发送功能,可以使用 UTL_SMTP 添加。

于 2010-02-17T22:29:51.153 回答