如何重定向DBMS_OUTPUT.PUT_LINE的输出到一个文件?(How to redirect

2019-07-18 18:12发布

我需要在PL / SQL调试推测的程序时间,我想用:

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

但我不明白的地方输出去,我怎么能重定向到包含所有我要收集的数据的日志文件?

Answer 1:

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


Answer 2:

作为替代写入文件,如何写入表? 而不是调用DBMS_OUTPUT.PUT_LINE的,你可以调用自己DEBUG.OUTPUT的程序是这样的:

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;

使用自治事务的可以保留从获得回滚(抛出一个异常如后)交易产生的调试消息,正如如果你使用一个文件发生。

所述g_debugging布尔变量是可需要调试输出时被默认为假,并设置为真包变量。

当然,你需要管理的是表,所以它不会永远成长! 一种方法是运行每晚/每周,并删除那些“老”任何调试信息的工作。



Answer 3:

利用设置SERVEROUTPUT上;

例如:

set serveroutput on;

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


Answer 4:

如果你只是测试你的PL / SQL中的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

像蟾蜍和SQL开发的IDE可以捕捉以其他方式输出,但我不熟悉如何。



Answer 5:

除了托尼的回答,如果你正在寻找,找出你的PL / SQL程序花费它的时间,它也是值得一试这在Oracle PL / SQL文件的一部分。



Answer 6:

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

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



Answer 7:

作为一个侧面说明,请记住,所有这些输出是在服务器端生成。

使用DBMS_OUTPUT,在服务器生成的文本,同时它执行你的查询和存储在缓冲区中。 然后它会被重定向到您的客户端应用程序在服务器完成查询数据检索。 也就是说,只有当查询结束得到这个信息。

随着UTL_FILE记录的所有信息将被存储在服务器上的文件。 当执行完成后,你将不得不导航到该文件来获取信息。

希望这可以帮助。



Answer 8:

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

本品采用Oracle目录 TMP_DIR ; 您必须声明,然后创建以下程序:

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)在数据库服务器上,打开一个壳

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


Answer 9:

一个古老的线程,但还有另外一种选择。

由于9i中可以使用流水线表函数。

首先,创建一个类型为VARCHAR的表:

CREATE TYPE t_string_max IS TABLE OF VARCHAR2(32767);

其次,包装你的代码在一个管道函数的声明:

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

更换所有DBMS_OUTPUT.PUT_LINE对于PIPE ROW

最后,这样称呼它:

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

希望能帮助到你。



Answer 10:

试试这个:

SELECT systimestamp INTO time_db FROM dual ;

DBMS_OUTPUT.PUT_LINE('time before procedure ' || time_db);


文章来源: How to redirect the output of DBMS_OUTPUT.PUT_LINE to a file?