【问题标题】:Oracle Triggers not inserting latest records into tablesOracle触发器未将最新记录插入表中
【发布时间】:2020-04-12 04:38:27
【问题描述】:

我有TABLE_1,这是这些记录的父表,位于SCHEMA_1 中,并在事务中从 JAVA/Node.js 应用程序填充。 在同一 SCHEMA_1 上也有以下触发器 (SCHEMA_1.TRIGGER_CALL_SP_OF_SCHEMA_2) 并调用另一个存储过程以填充到另一个 TABLE_2,它基于 Table_1 事务在 SCHEMA_2 中。

触发器:

create or replace trigger SCHEMA_1.TRIGGER_CALL_SP_OF_SCHEMA_2
  AFTER UPDATE OR INSERT OR DELETE ON SCHEMA_1.TABLE_1
  REFERENCING NEW AS NEW OLD AS OLD
  FOR EACH ROW
  DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
    SCHEMA_2.SP_OF_SCHEMA_2(:NEW.RECORD_ID);
    commit;
  EXCEPTION   WHEN OTHERS THEN
    RAISE;
END;

存储过程:

create or replace PROCEDURE SCHEMA_2.SP_OF_SCHEMA_2(P_RECORD_ID NUMBER ) AS
BEGIN
    DELETE FROM SCHEMA_2.TABLE_2 WHERE RECORD_ID = P_RECORD_ID;           
    FOR rec IN (SELECT RECORD_ID, COL2, COL3, COL4  from SCHEMA_1.TABLE_1 where RECORD_ID = P_RECORD_ID)
    LOOP
         INSERT INTO SCHEMA_2.TABLE_2 (RECORD_ID, COL2, COL3, COL4) VALUES(rec.RECORD_ID, rec.COL2, rec.COL3,rec.COL4 );
   END LOOP;
 COMMIT;
END; 

所以问题出在Table_2,它并不总是有最新记录。 例如:当第一个 record_Id 插入 Table_1 但在 Table_2 中没有任何条目时。 当第二次插入相同的 records_id 并在 Table_1 中插入另一个值时,但在 Table_2 中只有最后一个 record_id 并插入了详细信息。(同样不是最新条目)。以下是记录示例:(注意 - 两个表中都没有可用的任何 PK。)

表_1

+------------+-------+----------+---------+
| RECORD_ID  |  COL2 |   COL3   |  COL4   |
+------------+-------+----------+---------+
|          1 |   101 | abc      |  insert |
+------------+-------+----------+---------+

表_2

+------------+-------+----------+------+
| RECORD_ID  |  COL2 |   COL3   | COL4 |
+------------+-------+----------+------+

表_1

+------------+-------+----------+---------+
| RECORD_ID  |  COL2 |   COL3   |  COL4   |
+------------+-------+----------+---------+
|          1 |   101 | abc      |  insert |
|          1 |   102 | xyz      |  insert |
+------------+-------+----------+---------+

表_2

+------------+-------+----------+---------+
| RECORD_ID  |  COL2 |   COL3   |  COL4   |
+------------+-------+----------+---------+
|          1 |   101 | abc      |  insert |
+------------+-------+----------+---------+

这是任何数据库提交序列或任何事务相关问题或任何其他可能的情况的b'cze?如何实现这一点以保持 Table_2 始终更新。 提前致谢。

【问题讨论】:

  • 您的程序循环遍历(SELECT RECORD_ID, COL2, COL3, COL4 from SCHEMA_1.TABLE_1 where RECORD_ID = P_RECORD_ID),您确定这会返回任何值吗?
  • 既不在触发器中也不在过程中使用commit。这可能是对事务完整性的过度杀伤。

标签: oracle stored-procedures database-trigger


【解决方案1】:

触发器具有自主事务。

因此,触发触发器的插入/更新/删除与触发器中的过程调用处于单独的事务中。

事务只能查看其他人的已提交更改。

所以触发器中的事务看不到你插入的行!

create table t1 (
  c1 int
);
create table t2 (
  c1 int
);

create or replace trigger trig
after insert on t1
for each row
declare
  pragma autonomous_transaction;
begin
  insert into t2
    select * from t1
    where  c1 = :new.c1;

  dbms_output.put_line ( 'Rows added: ' || sql%rowcount );
  commit;
end;
/

insert into t1 values ( 1 );

Rows added: 0
commit;
insert into t1 values ( 1 );

Rows added: 1

select * from t2;

        C1
----------
         1

由于在没有自治事务的情况下引用 table_1 会引发变异触发错误 (ORA-04091),您需要重新考虑这个过程。

【讨论】:

    猜你喜欢
    • 2021-12-06
    • 1970-01-01
    • 2013-10-05
    • 2014-06-14
    • 2018-09-15
    • 1970-01-01
    • 2013-06-11
    • 2013-10-12
    • 1970-01-01
    相关资源
    最近更新 更多