1

我在一个有两个日期列的表中有以下情况,Start_DT并且End_DT.

+----+------------+------------+
| ID |  Start_DT  |   End_DT   |
+----+------------+------------+
|  1 | 01-01-2012 | 02-01-2012 |
|  2 | 02-01-2012 | 05-02-2012 |
|  3 | 05-02-2012 | 07-02-2012 |
+----+------------+------------+

每当我插入新行时,例如我想插入以下 tuple ('06-02-2012', '10-02-2012')End_DT按时间顺序排列的最后一个(前一个)行Start_DT时间重叠

所以,最后,插入我的新行后,表格将如下所示:

+----+------------+------------+
| ID |  Start_DT  |   End_DT   |
+----+------------+------------+
|  1 | 01-01-2012 | 02-01-2012 |
|  2 | 02-01-2012 | 05-02-2012 |
|  3 | 05-02-2012 | 06-02-2012 |
|  4 | 06-02-2012 | 10-02-2012 |
+----+------------+------------+

问题是我创建的触发器给了我一个错误,我理解这是我编写触发器的方式,但我不知道如何修改它以实现我想要的:

SQL Error: ORA-04091: table HISTORIC_TIME_TABLE is mutating, trigger/function may not see it

我们认为必须使用SELECT FOR UDPATE才能在前一行上加锁,以便进行更新。但是将此触发器更改为AFTER,我不确定我们是否可以在表上实现相同的锁定。

我的触发器代码是:

create or replace trigger trg_update_historic_time_table
before insert on HISTORIC_TIME_TABLE
for each row
declare

cursor upd_hist_tt_cur
is
    select start_dt, end_dt
    from HISTORIC_TIME_TABLE
    where (end_dt > sysdate)
    for update of end_dt;

begin

    for hist_cur_r in upd_hist_tt_cur loop
        if hist_cur_r.start_dt < :new.start_dt then
            update HISTORIC_TIME_TABLE
                set  end_dt = :new.start_dt
            where (start_dt = hist_cur_r.start_dt);
            commit;
        else
            :new.end_dt :=  hist_cur_r.start_dt;
        end if;
    end loop;

exception when no_data_found then null;
end;

我在Oracle 文档页面上在线发现BEFORE 触发器无法修改同一个表中的数据:

Before triggers cannot have INSERT, UPDATE or DELETE statements as their action.
Before triggers cannot call procedures that modify SQL data as their action.

所以,我正在考虑将我的触发器修改为一种AFTER类型,但是我将无法访问我的:new:old变量。

任何帮助是极大的赞赏。

4

0 回答 0