表正在变异,触发器可能看不到它

Posted

技术标签:

【中文标题】表正在变异,触发器可能看不到它【英文标题】:Table is mutating, trigger may not see it 【发布时间】:2019-06-23 13:00:55 【问题描述】:

创建触发器时没有错误。但是当我触发它时,会显示一条错误消息,表明该表正在发生变化。如何解决表变异的问题?

CREATE OR REPLACE TRIGGER tgr_invoice
AFTER UPDATE OF discharge_date
ON Admission
FOR EACH ROW
DECLARE
doc_fee NUMBER(5);
nights_stayed NUMBER(4);
room_price NUMBER(5);
room_fee NUMBER(9);
med_fee NUMBER(7, 2);
units_prescribed NUMBER(3);
price_per_unit NUMBER(7, 2);
total_fee NUMBER(8,2);
BEGIN
SELECT consult_fee INTO doc_fee     
FROM Doctor
WHERE staff_id IN (SELECT seen_by FROM Admission
WHERE patient_id = :NEW.patient_id
AND admission_date = :NEW.admission_date);

SELECT (discharge_date - admission_date) INTO nights_stayed 
FROM Admission 
WHERE patient_id = :NEW.patient_id
AND admission_date = :NEW.admission_date;

SELECT room_price INTO room_price 
FROM Room
WHERE room_no IN (SELECT room_no FROM Admission
WHERE patient_id = :NEW.patient_id
AND admission_date = :NEW.admission_date);

SELECT units_prescribed INTO units_prescribed 
FROM Prescription
WHERE patient_id = :NEW.patient_id
AND prescription_date = :NEW.admission_date;

SELECT price_per_unit INTO price_per_unit 
FROM Medicine
WHERE med_id IN (SELECT med_id FROM Prescription 
WHERE patient_id = :NEW.patient_id
AND prescription_date = :NEW.Admission_date);

room_fee := room_price * nights_stayed;
med_fee := units_prescribed * price_per_unit;
total_fee := room_fee + doc_fee + med_fee;

INSERT INTO Invoice VALUES(seq_inv_no.NEXTVAL, :NEW.patient_id, 
:NEW.admission_date, doc_fee, room_fee, med_fee, total_fee);
END;
/

当我更新准入表并输入出院日期时,出现错误'表SYSTEM.ADMISSION正在变异,触发器/函数可能看不到它'

【问题讨论】:

如果您描述了您尝试实现的逻辑,将会有所帮助。样本数据和所需结果的帮助。 您不应在SYSTEM(或任何其他Oracle 系统模式)中创建任何用户表或其他对象。为您的应用程序创建一个用户并在那里创建您的对象。 【参考方案1】:

我认为,由于在创建 DB 触发器的表的列的 :NEW 或 :OLD 值之间进行操作,而不是将 SELECT 语句用于行级触发器,我认为从赋值中派生值会更合适。因此,请考虑使用以下代码块:

CREATE OR REPLACE TRIGGER tgr_invoice AFTER UPDATE OF discharge_date ON Admission
FOR EACH ROW
DECLARE
    doc_fee NUMBER(5);
    nights_stayed NUMBER(4);
    room_price NUMBER(5);
    room_fee NUMBER(9);
    med_fee NUMBER(7, 2);
    units_prescribed NUMBER(3);
    price_per_unit NUMBER(7, 2);
    total_fee NUMBER(8,2);
BEGIN
 SELECT consult_fee 
   INTO doc_fee     
   FROM Doctor
  WHERE staff_id = :NEW.seen_by;

 nights_stayed := :NEW.discharge_date - :NEW.admission_date; 

 SELECT room_price 
   INTO room_price 
   FROM Room
  WHERE room_no = :NEW.room_no;

 SELECT units_prescribed 
   INTO units_prescribed 
   FROM Prescription
  WHERE patient_id = :NEW.patient_id
    AND prescription_date = :NEW.admission_date;

 SELECT price_per_unit INTO price_per_unit 
   FROM Medicine
  WHERE med_id IN (SELECT med_id 
                     FROM Prescription 
                    WHERE patient_id = :NEW.patient_id
                      AND prescription_date = :NEW.Admission_date);

 room_fee := room_price * nights_stayed;
 med_fee := units_prescribed * price_per_unit;
 total_fee := room_fee + doc_fee + med_fee;

 INSERT INTO Invoice 
 VALUES(seq_inv_no.NEXTVAL, :NEW.patient_id, :NEW.admission_date, 
        doc_fee, room_fee, med_fee, total_fee);
END;
/     

【讨论】:

非常感谢您的帮助,非常感谢。

以上是关于表正在变异,触发器可能看不到它的主要内容,如果未能解决你的问题,请参考以下文章

错误触发器:表正在变异,触发器/函数可能看不到它

表正在变异,触发器/函数可能看不到它;需要后/行级查询

ORA-04091: 表 JOSEP.EMP 正在变异,触发器/函数可能看不到它

ORA-04091: 表 [blah] 正在变异,触发器/函数可能看不到它

Oracle - 在没有触发器的情况下更新表时出现“表正在变异,触发器/函数可能看不到它”错误

表正在变异,触发器/函数可能看不到它/ORA-04088: 执行触发器时出错