如何跟踪导致错误的SQL

时间:2015-03-10 10:16:52

标签: sql oracle trace

我的数据库有很多种客户端,有时他们使用错误的SQL字符串。但是那些客户端是用不同的语言编写的,比如C ++,C,Java,.Net,我不可能学到所有这些。

例如,当ORA-00942发生错误时,如果我不知道如何在客户端打印SQL文本,我怎么能通过使用Oracle或某些Oracle工具来知道SQL文本是什么?

2 个答案:

答案 0 :(得分:1)

是的,这是非常有可能的。这是 SQL*Plus 中的新功能。请阅读SQL*Plus error logging – New feature release 11.1以深入了解该功能。

注意:默认情况下,SQL * Plus错误日志记录设置为OFF。因此,您需要“设置错误记录”才能使用 SPERRORLOG表

SPERRORLOG 表格如下:

SQL> desc sperrorlog;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------

 USERNAME                                           VARCHAR2(256)
 TIMESTAMP                                          TIMESTAMP(6)
 SCRIPT                                             VARCHAR2(1024)
 IDENTIFIER                                         VARCHAR2(256)
 MESSAGE                                            CLOB
 STATEMENT                                          CLOB

例如,

SQL> set errorlogging on
SQL>
SQL> SELECT * FROM dula;
SELECT * FROM dula
              *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL>
SQL> SELECT USERNAME, TIMESTAMP, MESSAGE, STATEMENT FROM sperrorlog;

USERNAME   TIMESTAMP                      MESSAGE                                            STATEMENT
---------- ------------------------------ -------------------------------------------------- ------------------
LALIT      10-MAR-15 04.08.13.000000 PM   ORA-00942: table or view does not exist            SELECT * FROM dula

SQL>

因此,出现错误的语句现在记录在SPERRORLOG表中。

编辑

  

我的数据库有很多种客户端,有时他们使用错误的SQL字符串。但这些客户端是用不同的语言编写的,如C ++,C,Java,.Net

上述解决方案仅适用于通过SQL * Plus执行的脚本。如果查询是通过应用程序客户端执行的,那么为了找到完整的信息,您可以跟踪应用程序用来与数据库交互的整个会话。

您可以查看此article以获取有关如何生成跟踪文件的示例。

答案 1 :(得分:1)

AFAIK" only"选项是跟踪整个服务器。您必须创建一种特殊类型的触发器AFTER SERVERERROR ON DATABASE

请参阅:http://www.red-database-security.com/scripts/oracle_error_trigger.html

可能有其他方法可以做到这一点,但它们太低级了。 类似:OCI跟踪,JDBC跟踪或某些alter system set events ...

摘要:会话跟踪不包含解析失败的语句。

更高级的主题:

  • JDBC驱动程序支持标准logging
  • OCI驱动程序支持"拦截器"图书馆。你必须设置一些环境变量,让它指向我们自己的.dll库。 OCI驱动程序将加载此库,并将在此各种事件上从此lib调用回调。它在OCI编程参考和AFAIK中描述,您可以在SF
  • 上找到一些示例拦截器库
  • .Net跟踪记录在案here