触发检查条件

时间:2018-08-29 10:49:20

标签: oracle triggers

我在表t1上有一个触发器。如果在t1中插入了任何不良记录,则需要在表2中插入。但是它是变异的。解决此问题的任何帮助将不胜感激。

我正在使用oracle 12c。

create or replace 
TRIGGER test_air_tr
    AFTER INSERT
    ON t1 
    FOR EACH ROW

DECLARE

  v_count NUMBER;

BEGIN
--condition to check bad record. 
SELECT COUNT(*)  INTO v_count  FROM t1
     WHERE  col1=:new.col2;

IF (v_count>0) THEN 
    INSERT INTO t2
        (
          col1 ,           
          col2  )        
        VALUES
        (
         :new.col1 ,           
         :new.col2
        ) ;
END IF;

 EXCEPTION
       WHEN DUP_VAL_ON_INDEX  THEN
        UPDATE t2
            SET col2               =:new.col2

            WHERE col1       =:new.col1;
END;

1 个答案:

答案 0 :(得分:0)

发生错误是因为在触发器中还查询了定义触发器的表。该问题的一种解决方案是使用编译指示自主事务,并在使用该编译指示的过程中移动触发器的逻辑,然后在触发器中调用此过程。

在我的系统中,我能够重现该错误并验证以下解决方案是否有效:

SQL> desc t1
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 COL1                                               NUMBER
 COL2                                               NUMBER

(Same structure for t2 table).

CREATE OR REPLACE PROCEDURE check_bad_data (p_col1 NUMBER, p_col2 NUMBER)
IS
   PRAGMA AUTONOMOUS_TRANSACTION;
   v_cnt   NUMBER;
BEGIN
   SELECT COUNT (*)
     INTO v_cnt
     FROM t1
    WHERE col1 = p_col2;

   IF (v_cnt > 0)
   THEN
      INSERT INTO t2 (col1, col2)
           VALUES (P_col1, P_col2);
   END IF;
EXCEPTION
   WHEN DUP_VAL_ON_INDEX
   THEN
      UPDATE t2
         SET col2 = p_col2
       WHERE col1 = p_col1;
END;
/

--

create or replace 
TRIGGER test_air_tr
    AFTER INSERT
    ON t1 
    FOR EACH ROW
begin

 check_bad_data(:new.col1,:new.col2);

end;

SQL> insert into t1 values(1,2);

1 row created. 

SQL> commit;

Commit complete.

请注意,这只是一种可能的解决方案,也可以有其他方法。我看到了该URL,它帮助我获得了以下解决方案: https://www.databasejournal.com/features/oracle/mutating-table-errorin-oraclewhyithappensand-what-you-can-doabout-it.html

-在我的系统中:

SQL> delete from t1;

9 rows deleted.

SQL> delete from t2;

3 rows deleted.

SQL> commit;

Commit complete.

SQL> insert into t1 values(1,2);

1 row created.

SQL> select * from t1;

      COL1       COL2
---------- ----------
         1          2

SQL> select * from t2;

no rows selected

SQL> insert into t1 values (3,4);

1 row created.

SQL> select * from t2;

no rows selected

SQL> commit;

Commit complete.

SQL> select * from t2;

no rows selected

SQL> insert into t1 values (4,1);

1 row created.

SQL> select * from t1;

      COL1       COL2
---------- ----------
         3          4
         4          1
         1          2

SQL> select * from t2;

      COL1       COL2
---------- ----------
         4          1