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
table Admin.PATIENT_REGISTRATIONが変化しているため、トリガー/関数に表示されない場合が あります。テーブル%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;

これで、患者ごとに1つのPATIENT_REGISTRATIONレコードがあることがわかりました(つまり、PATIENT_IDが主キーです)。また、私のソリューションが機能し、変更テーブルエラーが発生しないこともわかりました。

于 2013-01-06T14:33:20.403 に答える
0

最初に、このようにロジックを設計するべきではないことを述べたいと思います。あなたのトリガーの上に何があるのか​​わかりませんが、更新と値を取得するのはその上位層の役割である必要があります。アプリケーションロジックをトリガーに入れると、混乱を招くだけです。PAID_AMOUNTPENDING

だが。データベース上のアプリケーションを制御できず、これを実行する必要がある場合は、トリガーをに変更する必要がありますfor each statementNEW_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

トリガーがそれ自体をトリガーするのを防ぐため。

'statement'トリガー内で、トリガーの'base'テーブルを変更できます。

ここでそれについてもっと読むことができます。

于 2013-01-06T14:30:30.083 に答える