有没有办法刷新 Oracle 中 PL/SQL 的输出?
我有一个从 shell 脚本中调用的 SQL 脚本,需要很长时间才能运行。它当前在不同点包含 dbms_output.put_line
语句。这些打印语句的输出会出现在日志文件中,但仅在脚本完成后才会出现。
有什么方法可以确保脚本运行时输出出现在日志文件中?
I have an SQL script that is called from within a shell script and takes a long time to run. It currently contains dbms_output.put_line
statements at various points. The output from these print statements appear in the log files, but only once the script has completed.
Is there any way to ensure that the output appears in the log file as the script is running?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
并不真地。 DBMS_OUTPUT 的工作方式是这样的:您的 PL/SQL 块在数据库服务器上执行,不与客户端交互。因此,当您调用 PUT_LINE 时,它只是将该文本放入服务器内存中的缓冲区中。当您的 PL/SQL 块完成时,控制权将返回给客户端(在本例中我假设是 SQLPlus);此时,客户端通过调用 GET_LINE 从缓冲区中获取文本并显示它。
因此,使输出更频繁地出现在日志文件中的唯一方法是将大型 PL/SQL 块分解为多个较小的块,以便更频繁地将控制权返回给客户端。这可能不切实际,具体取决于您的代码正在执行的操作。
其他替代方法是使用 UTL_FILE 写入文本文件(可以随时刷新该文件),或者使用自主事务过程将调试语句插入数据库表中并在每条语句后提交。
Not really. The way DBMS_OUTPUT works is this: Your PL/SQL block executes on the database server with no interaction with the client. So when you call PUT_LINE, it is just putting that text into a buffer in memory on the server. When your PL/SQL block completes, control is returned to the client (I'm assuming SQLPlus in this case); at that point the client gets the text out of the buffer by calling GET_LINE, and displays it.
So the only way you can make the output appear in the log file more frequently is to break up a large PL/SQL block into multiple smaller blocks, so control is returned to the client more often. This may not be practical depending on what your code is doing.
Other alternatives are to use UTL_FILE to write to a text file, which can be flushed whenever you like, or use an autonomous-transaction procedure to insert debug statements into a database table and commit after each one.
如果可能的话,您应该用您自己的函数替换对 dbms_output.put_line 的调用。
以下是此函数的代码
WRITE_LOG
- 如果您希望能够在 2 个日志记录解决方案之间进行选择:将日志写入表在自主事务
或直接写入托管数据库的数据库服务器
这使用Oracle 目录
TMP_DIR
WRITE_LOG
然后
WRITE_LOG< /code>
程序可以在两种用途之间切换,或者被停用以避免性能损失(
g_DEBUG:=FALSE
)。以下是如何测试上述内容:
1) 从 SQLPLUS 启动此(文件模式):
2) 在数据库服务器上,打开 shell 并
If it is possible to you, you should replace the calls to dbms_output.put_line by your own function.
Here is the code for this function
WRITE_LOG
-- if you want to have the ability to choose between 2 logging solutions:write logs to a table in an autonomous transaction
or write directly to the DB server that hosts your database
This uses the Oracle directory
TMP_DIR
WRITE_LOG
Then the
WRITE_LOG
procedure which can switch between the 2 uses, or be deactivated to avoid performances loss (g_DEBUG:=FALSE
).And here is how to test the above:
1) Launch this (file mode) from your SQLPLUS:
2) on the database server, open a shell and
两种替代方案:
您可以使用自治事务将日志记录详细信息插入日志记录表中。您可以在另一个 SQLPLUS/Toad/sql Developer 等会话中查询此日志记录表。您必须使用自治事务才能提交日志记录,而不会干扰主 sql 脚本中的事务处理。
另一种选择是使用返回日志信息的管道函数。请参阅此处的示例: http://berxblog.blogspot.com /2009/01/pipelined-function-vs-dbmsoutput.html 当您使用管道函数时,您不必使用另一个 SQLPLUS/Toad/sql 开发人员等...会话。
Two alternatives:
You can insert your logging details in a logging table by using an autonomous transaction. You can query this logging table in another SQLPLUS/Toad/sql developer etc... session. You have to use an autonomous transaction to make it possible to commit your logging without interfering the transaction handling in your main sql script.
Another alternative is to use a pipelined function that returns your logging information. See here for an example: http://berxblog.blogspot.com/2009/01/pipelined-function-vs-dbmsoutput.html When you use a pipelined function you don't have to use another SQLPLUS/Toad/sql developer etc... session.
当调用过程
DBMS_OUTPUT.get_line
时,读取DBMS_OUTPUT
的缓冲区。如果您的客户端应用程序是 SQL*Plus,则意味着只有在过程完成后才会刷新它。您可以应用 此 SO 将
DBMS_OUTPUT
缓冲区写入文件。the buffer of
DBMS_OUTPUT
is read when the procedureDBMS_OUTPUT.get_line
is called. If your client application is SQL*Plus, it means it will only get flushed once the procedure finishes.You can apply the method described in this SO to write the
DBMS_OUTPUT
buffer to a file.使用
dbms_application_info()
设置会话元数据MODULE和/或ACTION。通过 OEM 进行监控,例如:
Set session metadata MODULE and/or ACTION using
dbms_application_info()
.Monitor with OEM, for example:
如果您可以从 PL/SQL 环境访问系统 shell,您可以调用 netcat:
p_msg
- 是一条日志消息v_host
是运行 python 脚本的主机,它从端口v_port
上的套接字读取数据。当我为实时 shell 编写 aplogr 时,我使用了这种设计pl/sql 日志监控。
If you have access to system shell from PL/SQL environment you can call netcat:
p_msg
- is a log messagev_host
is a host running python script that reads data from socket on portv_port
.I used this design when I wrote aplogr for real-time shell and pl/sql logs monitoring.