1
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-”表 %s.%s 正在发生变化,触发器/函数可能看不到它”

4

2 回答 2

3

我们可以在触发器中操作 :NEW 值:

if :new.PAIDAMOUNT_TEMP != :old.PAIDAMOUNT_TEMP
then
    :new.PAID_AMOUNT := :new.PAIDAMOUNT_TEMP + :old.DIFFERENCE;
    :new.PENDING := ABS(:new.PAIDAMOUNT_TEMP - :new.DUES);
    :new.difference := :new.total_charges - :new.per_day_charges;
end if;

现在我们知道每个患者有一个 PATIENT_REGISTRATION 记录(即 PATIENT_ID 是主键),我们也知道我的解决方案可以工作,并且您不会收到变异表错误。

于 2013-01-06T14:33:20.403 回答
0

首先我想说的是,你不应该以这种方式设计你的逻辑。我不知道您的触发器上方是什么,但它应该是上层更新PAID_AMOUNTPENDING价值的角色。将应用程序逻辑放入触发器中只会导致混乱。

但。如果您无法控制数据库上方的应用程序并且必须这样做,那么您应该将触发器更改为for each statement. 在它内部创建一个循环来迭代NEW_TABLE并相应地更新每一行。但请记住对您的更新设置条件,如下所示:

UPDATE admin.patient_registration d
    set d.PAID_AMOUNT = p_PAIDAMOUNT_TEMP + p_DIFFERENCE 
    where d.PAID_AMOUNT != (p_PAIDAMOUNT_TEMP + p_DIFFERENCE) -- this is important
    and d.patient_id != p_patient_id

以防止触发器自行触发。

在“语句”触发器中,您可以修改触发器的“基”表。

在这里你可以阅读更多关于它的信息。

于 2013-01-06T14:30:30.083 回答