如何将DBMS_OUTPUT.PUT_LINE的输出重定向到文件?

45 oracle plsql oracle-sqldeveloper dbms-output

我需要在pl/sql中调试以计算程序的次数,我想使用:

SELECT systimestamp FROM dual INTO time_db;
DBMS_OUTPUT.PUT_LINE('time before procedure ' || time_db);
Run Code Online (Sandbox Code Playgroud)

但我不明白输出的位置,如何将其重定向到包含我想要收集的所有数据的日志文件?

Vin*_*rat 37

DBMS_OUTPUT不是最好的调试工具,因为大多数环境本身不使用它.DBMS_OUTPUT但是,如果要捕获输出,则只需使用该DBMS_OUTPUT.get_line过程.

这是一个小例子:

SQL> create directory tmp as '/tmp/';

Directory created

SQL> CREATE OR REPLACE PROCEDURE write_log AS
  2     l_line VARCHAR2(255);
  3     l_done NUMBER;
  4     l_file utl_file.file_type;
  5  BEGIN
  6     l_file := utl_file.fopen('TMP', 'foo.log', 'A');
  7     LOOP
  8        EXIT WHEN l_done = 1;
  9        dbms_output.get_line(l_line, l_done);
 10        utl_file.put_line(l_file, l_line);
 11     END LOOP;
 12     utl_file.fflush(l_file);
 13     utl_file.fclose(l_file);
 14  END write_log;
 15  /

Procedure created

SQL> BEGIN
  2     dbms_output.enable(100000);
  3     -- write something to DBMS_OUTPUT
  4     dbms_output.put_line('this is a test');
  5     -- write the content of the buffer to a file
  6     write_log;
  7  END;
  8  /

PL/SQL procedure successfully completed

SQL> host cat /tmp/foo.log

this is a test
Run Code Online (Sandbox Code Playgroud)


Ton*_*ews 31

作为写入文件的替代方法,如何写入表格?您可以调用自己的DEBUG.OUTPUT过程,而不是调用DBMS_OUTPUT.PUT_LINE:

procedure output (p_text varchar2) is
   pragma autonomous_transaction;
begin
   if g_debugging then
      insert into debug_messages (username, datetime, text)
      values (user, sysdate, p_text);
      commit;
   end if;
end;
Run Code Online (Sandbox Code Playgroud)

使用自治事务允许您保留从回滚的事务(例如,在引发异常之后)生成的调试消息,如果您使用文件时会发生这种情况.

g_debugging布尔变量是一个包变量,可以默认为false,并在需要调试输出时设置为true.

当然,您需要管理该表,以便它不会永远增长!一种方法是每晚/每周运行的作业,并删除任何"旧"的调试消息.

  • +1用于回答真正的基础问题("我如何从Oracle登录?")而不是表面问题. (2认同)

Ton*_*ews 14

如果您只是在SQL Plus中测试PL/SQL,可以将它指向如下文件:

spool output.txt
set serveroutput on

begin
  SELECT systimestamp FROM dual INTO time_db;
  DBMS_OUTPUT.PUT_LINE('time before procedure ' || time_db);
end;
/

spool off
Run Code Online (Sandbox Code Playgroud)

像Toad和SQL Developer这样的IDE可以用其他方式捕获输出,但我不熟悉如何.


Mah*_*afy 14

使用set serveroutput on;

例如:

set serveroutput on;

DECLARE
x NUMBER;
BEGIN
x := 72600;
dbms_output.put_line('The variable X = '); dbms_output.put_line(x);
END;
Run Code Online (Sandbox Code Playgroud)


Ian*_*ter 5

除了Tony的回答,如果你想找出你的PL/SQL程序花费时间的地方,还值得查看部分Oracle PL/SQL文档.


Raf*_*tro 4

使用UTL_FILE代替DBMS_OUTPUT会将输出重定向到文件:

http://oreilly.com/catalog/oraclebip/chapter/ch06.html