触发检查条件

问题描述 投票:0回答:1

我在表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;
oracle triggers
1个回答
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
© www.soinside.com 2019 - 2024. All rights reserved.