捕获ORACLE查询导致表溢出

时间:2014-08-21 21:01:41

标签: java sql oracle

我遇到的问题是Java进程(我无法控制)是将行插入表中并导致溢出。我无法拦截查询,ORACLE引发的异常并不能提供信息。它只提到溢出,但没有提到它发生在哪一列。

我想知道哪个查询导致此溢出以及插入的值。

我尝试在表上创建一个触发器BEFORE INSERT,将行复制到另一个我可以稍后读取的临时表中,但是当溢出发生时看起来似乎没有运行触发器。

触发语法:

CREATE OR REPLACE TRIGGER OVERFLOW_TRIGGER
BEFORE INSERT
    ON VICTIM_TABLE
    FOR EACH ROW
BEGIN
    insert into QUERIES_DUMP values (
        :old.COL1, :old.COL2, :old.COL3, 
        :old.COL4, :old.COL5, :old.COL6, 
        :old.COL7, :old.COL8, :old.COL9, 
        :old.COL10, :old.COL11, :old.COL12
    );
END;
/

表QUERIES_DUMP具有与失败表相同的结构,但NUMBER和VARCHAR2列被推到最大容量。我希望得到一个查询列表,然后找出哪些是违反规则的。

即使设置为在插入之前运行,是否期望触发器在溢出的情况下不运行?

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for Solaris: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production

EDIT1:

抛出的错误是:

Description: Error while query: INSERT INTO 
...
ORA-01438: value larger than specified precision allowed for this column

我所知道的是,在任何地方都没有插入错误的类型。它很可能是其中一个数字字段的长度,但是它们很多并且插入过程需要一个多小时,所以我不能强行猜测列。

我已经考虑过备份表并使用更大的列创建一个新的victim_table,但是这个过程实际上插入了很多其他表以及复杂的数据模型中,并且DB有一些敏感的信息所以我不能通过移动来危害其一致性。

我尝试了一个INSTEAD OF触发器,但ORACLE似乎不接受INSTEAD OF表示插入。

我添加了JDBC层的日志记录,但是我得到的查询没有值,只有'?'

Description: Error while query: INSERT INTO VICTIM_TABLE ( . . . ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)

1 个答案:

答案 0 :(得分:1)

这取决于具体的错误(包括ORA-xxxxx错误号总是非常感谢)。

如果问题是Java应用程序试图插入无法转换为表的数据类型的值,那么在触发器运行之前可能会抛出该错误。数据类型验证必须在触发器执行之前进行。

想象一下,如果在触发器运行后发生数据类型验证会发生什么。如果Java应用程序为col1传递了无效值,那么在触发器内部,:new.col1将具有基础表中col1所具有的数据类型,但会有无效值。因此,对该字段的任何引用都需要引发错误 - 您无法将无效值记录到您的表中。

您确定无法以某种方式拦截查询吗?例如,如果您将victim_table重命名为victim_table_base,则创建一个名为victim_table的视图,其中包含更大的数据类型,然后在视图上定义instead of触发器,以验证数据和将其插入表中,您可以识别哪些值无效。或者,由于您的Java应用程序使用JDBC(可能)与数据库交互,因此您应该能够在JDBC层启用日志记录以查看正在传递的参数值。