如何将DBMS_OUTPUT.PUT_LINE的输出redirect到一个文件?

我需要在pl / sql中debugging数字的时间程序,我想用:

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

但我不明白输出到哪里,我如何将它redirect到一个日志文件,其中将包含我想收集的所有数据?

DBMS_OUTPUT不是debugging的最佳工具,因为大多数环境本身并不使用它。 如果要捕获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 

作为写入文件的替代方法,如何写入表格? 您可以调用您自己的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; 

自治事务的使用允许您保留从回滚的事务(例如,在引发exception之后)产生的debugging消息,就像在使用文件时会发生的那样。

g_debugging布尔variables是一个包variables,当需要debugging输出时可以默认为false,并设置为true。

当然,你需要pipe理这张桌子,这样它才不会永远长大! 一种方法是每晚每周运行一次,并删除任何“旧”的debugging消息。

使用set serveroutput;

例如:

 set serveroutput on; DECLARE x NUMBER; BEGIN x := 72600; dbms_output.put_line('The variable X = '); dbms_output.put_line(x); END; 

如果你只是在SQL Plus中testing你的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 

像Toad和SQL Developer这样的IDE可以用其他方式捕获输出,但是我不太清楚。

除了Tony的回答之外,如果您正在寻找PL / SQL程序花在哪里的时间,那么还需要查看这部分Oracle PL / SQL文档。

使用UTL_FILE而不是DBMS_OUTPUT将输出redirect到一个文件:

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

请注意,所有这些输出都是在服务器端生成的。

使用DBMS_OUTPUT,文本在执行查询并存储在缓冲区时在服务器中生成。 然后在服务器完成查询数据检索时redirect到您的客户端应用程序。 也就是说,只有在查询结束时才能得到这个信息。

使用UTL_FILElogging的所有信息将被存储在服务器中的文件中。 当执行完成后,你将不得不导航到这个文件来获取信息。

希望这可以帮助。

它可能直接写入一个文件到承载你的数据库的数据库服务器,这将随着你的PL / SQL程序的执行而改变。

这使用Oracle目录 TMP_DIR ; 你必须声明它,并创build下面的过程:

 CREATE OR REPLACE PROCEDURE write_log(p_log varchar2) -- file mode; thisrequires --- CREATE OR REPLACE DIRECTORY TMP_DIR as '/directory/where/oracle/can/write/on/DB_server/'; AS l_file utl_file.file_type; BEGIN l_file := utl_file.fopen('TMP_DIR', 'my_output.log', 'A'); utl_file.put_line(l_file, p_log); utl_file.fflush(l_file); utl_file.fclose(l_file); END write_log; / 

以下是如何使用它:

1)从你的SQL * PLUS客户端启动它:

 BEGIN write_log('this is a test'); for i in 1..100 loop DBMS_LOCK.sleep(1); write_log('iter=' || i); end loop; write_log('test complete'); END; / 

2)在数据库服务器上,打开一个shell和

     tail -f -n500 /directory/where/oracle/can/write/on/DB_server/my_output.log

一个古老的线程,但有另一种select。

自9i以来,您可以使用stream水线表格function。

首先,创build一个types为varchar的表格:

 CREATE TYPE t_string_max IS TABLE OF VARCHAR2(32767); 

其次,将代码包装在stream水线函数声明中:

 CREATE FUNCTION fn_foo (bar VARCHAR2) -- your params RETURN t_string_max PIPELINED IS -- your vars BEGIN -- your code END; / 

replacePIPE ROW所有DBMS_OUTPUT.PUT_LINE

最后,这样称呼它:

 SELECT * FROM TABLE(fn_foo('param')); 

希望能帮助到你。

尝试这个:

 SELECT systimestamp INTO time_db FROM dual ; DBMS_OUTPUT.PUT_LINE('time before procedure ' || time_db); 
    Interesting Posts