create or replace trigger admin.patreg_paid_amt_temp
before UPDATE OF PAIDAMOUNT_TEMP ON admin.patient_registration
REFERENCING OLD AS OLD NEW AS NEW
For EACH ROW
BEGIN
if :new.PAIDAMOUNT_TEMP != :old.PAIDAMOUNT_TEMP
then
UPDATE admin.patient_registration d
set d.PAID_AMOUNT = :new.PAIDAMOUNT_TEMP + d.DIFFERENCE ,
d.PENDING = ABS(:new.PAIDAMOUNT_TEMP - d.DUES)
where d.PATIENT_ID = :new.PATIENT_ID;
end if;
END;
我知道这是因为触发器无法更改其读取的表的内容 .
任何人都可以帮助我完成这个
当我写这个查询后发生错误
update admin.patient_registration set paidamount_temp= 1000 where patient_id=11;
执行请求的操作时遇到错误
ORA-04091 :表Admin.PATIENT_REGISTRATION正在变异,触发器/函数可能看不到它
ORA-06512 :在"ADMIN.PATREG_PAID_AMT_TEMP",第4行
ORA-04088 :执行触发器时出错"ADMIN.PATREG_PAID_AMT_TEMP"
04091. 000000- "table %s.%s is mutating,trigger/function may not see it"
2 回答
我们可以在触发器中操纵:NEW值:
现在我们知道每个患者有一个PATIENT_REGISTRATION记录(即PATIENT_ID是主键)我们也知道我的解决方案将起作用,你不会得到变异表错误 .
首先,我想说明你不应该以这种方式设计你的逻辑 . 我不知道你的触发器上方是什么,但它应该是更新
PAID_AMOUNT
和PENDING
值的上层角色 . 将应用程序逻辑置于触发器中只会导致混乱 .但 . 如果您无法控制数据库上方的应用程序并且必须执行此操作,那么您应该将触发器更改为
for each statement
. 在它内部创建一个循环迭代NEW_TABLE
并相应地更新每一行 . 但请记住在您的更新中添加如下条件:防止触发器触发自身 .
在'statement'触发器中,您可以修改trigger的'base'表 .
Here你可以阅读更多相关信息 .