在Oracle中有没有办法刷新PL/SQL的输出?
我有一个SQL脚本,它是从shell脚本中调用的,需要很长时间才能运行。它当前包含在Oracle中有没有办法刷新PL/SQL的输出?,sql,oracle,plsql,dbms-output,Sql,Oracle,Plsql,Dbms Output,我有一个SQL脚本,它是从shell脚本中调用的,需要很长时间才能运行。它当前包含dbms\u输出。在不同的点上放置行语句。这些打印语句的输出显示在日志文件中,但仅在脚本完成后显示 有没有办法确保脚本运行时输出显示在日志文件中?调用过程DBMS\u output.get\u line时读取DBMS\u output的缓冲区。如果您的客户端应用程序是SQL*Plus,则意味着只有在过程完成后才会刷新它 您可以应用中所述的方法将DBMS\u输出缓冲区写入文件。实际上不是这样。DBMS_输出的工作方式
dbms\u输出。在不同的点上放置行
语句。这些打印语句的输出显示在日志文件中,但仅在脚本完成后显示
有没有办法确保脚本运行时输出显示在日志文件中?调用过程
DBMS\u output.get\u line
时读取DBMS\u output
的缓冲区。如果您的客户端应用程序是SQL*Plus,则意味着只有在过程完成后才会刷新它
您可以应用中所述的方法将
DBMS\u输出
缓冲区写入文件。实际上不是这样。DBMS_输出的工作方式是:PL/SQL块在数据库服务器上执行,而不与客户机交互。因此,当您调用PUT_LINE时,它只是将文本放入服务器内存中的缓冲区中。当PL/SQL块完成时,控制返回给客户机(在本例中,我假设为SQLPlus);此时,客户端通过调用GET_LINE从缓冲区中获取文本,并显示它
因此,使输出更频繁地出现在日志文件中的唯一方法是将大型PL/SQL块分解为多个较小的块,以便更频繁地将控制权返回给客户机。这可能不实用,这取决于您的代码正在做什么
其他替代方法是使用UTL_文件写入文本文件,文本文件可以随时刷新,或者使用自治事务过程将调试语句插入数据库表,并在每个语句之后提交。两种替代方法:
如果可能,您应该用自己的函数替换对dbms_output.put_line的调用 以下是此功能的代码
写入日志
——如果您希望能够在两种日志解决方案之间进行选择:
将日志写入
或者直接写入托管数据库的DB服务器
这使用了TMP\U目录
CREATE OR REPLACE PROCEDURE to_dbg_file(p_fname varchar2, p_log varchar2)
-- file mode:
-- requires
--- 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', p_fname, 'A');
utl_file.put_line(l_file, p_log);
utl_file.fflush(l_file);
utl_file.fclose(l_file);
END to_dbg_file;
/
写入日志
然后,写入日志
过程可以在两种使用之间切换,或者被停用以避免性能损失(g\u DEBUG:=FALSE
)
下面是如何测试上述各项:
1) 从SQLPLUS启动此(文件模式):
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
如果您可以从PL/SQL环境访问system shell,则可以调用netcat:
BEGIN RUN_SHELL('echo "'||p_msg||'" | nc '||p_host||' '||p_port||' -w 5'); END;
p_msg
-是一条日志消息
v_-host
是一个运行python脚本的主机,该脚本从端口v_-port
上的套接字读取数据
我在编写实时shell和pl/sql日志监控时使用了这种设计。使用
dbms\u application\u info()设置会话元数据模块和/或操作
使用OEM进行监控,例如:
Module: ArchiveData
Action: xxx of xxxx
请不要在多个问题中添加[相同答案](链接)。回答最好的一个,并将其余的标记为重复项。请参阅,您也可以直接监视ASH(v$active\u session\u history)
BEGIN RUN_SHELL('echo "'||p_msg||'" | nc '||p_host||' '||p_port||' -w 5'); END;
Module: ArchiveData
Action: xxx of xxxx