【发布时间】:2014-04-25 07:09:06
【问题描述】:
作为审计/历史记录功能的一部分,我想使用 AFTER UPDATE 触发器或任何其他触发器来处理以下场景,请告诉我。 情景——
- 将有 2 个表 -- 基表和历史表
- 更新基表中的任何记录时,第一次在历史表中插入相同的记录(要更新),并使用旧值。
- 使用基表中的新值更新记录。
我正在使用以下触发器,出现死锁情况。请建议解决此问题。
create table Base_table(
SYMBOL_ID NUMBER(9) primary key,
SYMBOL_NAME VARCHAR2(20) ,
PRICE NUMBER(9) ,
VERSION NUMBER(1)
)
organization index;
create table base_table_hist(
ID NUMBER(9) primary key,
SYMBOL_ID NUMBER(9) ,
SYMBOL_NAME VARCHAR2(20) ,
PRICE NUMBER(9),
VERSION NUMBER(1) ,
constraint other_symbolid foreign key(symbol_id) references test_symbol(symbol_id)
)
organization index;
************************************************************
create or replace Trigger Symbol_Ver
AFTER UPDATE ON Base_table
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
DECLARE
new_version number(5);
--Pragma AUTONOMOUS_TRANSACTION;
Sid number(9);
begin
if (:New.symbol_id <> :Old.symbol_id) OR (:New.price <> :Old.price) then
new_version:= :Old.version+1;
--insert into history table
insert into base_table_hist (id, symbol_id, symbol_name,price,version)
values (symbol_seq.nextval, :OLD.symbol_id, :OLD.symbol_name, :OLD.price, :OLD.version);
commit;
DBMS_OUTPUT.put_line('new_version..'||new_version);
end if;
if (:New.symbol_id <> :Old.symbol_id) OR (:New.price <> :Old.price) then
update base_table set version=new_version where symbol_id=:Old.symbol_id;
end if;
end;
【问题讨论】:
-
真的是死锁吗?不是变异表错误,也不是资源不足(因为触发器会从其中的递归更新中重复触发)?
-
显示死锁错误 (ORA-00060)。为避免重复触发条件更改为 (if :New.version = Old.Version) 然后 INSERT 和 UPDATE 操作。
-
但是你仍然在触发一个额外的更新,这很丑陋,我很惊讶工作。为什么不在
before触发器中调整版本(设置:new.version)并创建历史记录,而不是做额外的DML?