ORA-04091 表 * 正在发生变化,触发器/函数可能看不到它

问题描述 投票:0回答:2

我正在开发一个向客户出租船只的项目,并根据他们输入的信息向他们提供船只。在这个项目的一部分中,我想创建一个触发器,根据您乘船离开的时间和返回的时间,它将计算天数,然后将钱退还给客户余额或收取额外费用。我的触发器设置是这样的 -

CREATE OR REPLACE TRIGGER BALANCE_FEE
AFTER INSERT ON CHARTERS
FOR EACH ROW 
DECLARE
FEE NUMBER;
ACL_DATE DATE;
EXP_DATE DATE;
GRP_ID NUMBER;

BEGIN

SELECT ACL_RETURN_DATE, EXP_RETURN_DATE, GRP_ID INTO ACL_DATE, EXP_DATE, GRP_ID FROM CHARTERS;


IF ACL_DATE > EXP_DATE
THEN
FEE := (ACL_DATE - EXP_DATE) * 75;

IF ACL_DATE < EXP_DATE
THEN
FEE := (ACL_DATE - EXP_DATE)* -20;

ELSE
FEE := 0;
END IF;
END IF;
UPDATE CUSTOMER
     SET CUSTOMER.BALANCE = CUSTOMER.BALANCE + FEE
     WHERE CUSTOMER.GRP_ID = GRP_ID;
END;
/
SHOW ERROR;

如果这也有帮助的话,我有两个与此触发器相关的表。

CREATE TABLE CUSTOMER (
    CUS_FNAME VARCHAR(20),
    CUS_LNAME VARCHAR(20),
    GENDER VARCHAR(20),
    PHONENUM NUMBER(10),
    CITY VARCHAR(20),
    PARTY_COUNT INT,
    GRP_ID VARCHAR(20) PRIMARY KEY,
    BALANCE NUMBER);

CREATE TABLE CHARTERS (
    CHARTER_ID VARCHAR(20),
    BOAT_ID VARCHAR(20) REFERENCES BOAT(BOAT_ID),
    GRP_ID VARCHAR(20) REFERENCES CUSTOMER(GRP_ID),
    EXP_RETURN_DATE DATE,
    ACL_RETURN_DATE DATE);

当我运行代码时,我收到此错误报告

INSERT INTO CHARTERS (CHARTER_ID,BOAT_ID,EXP_RETURN_DATE,ACL_RETURN_DATE,GRP_ID) VALUES ('T003','B003',DATE '2019-05-5',DATE '2019-05-07','G003')
Error report -
ORA-04091: table ADMIN_BF.CHARTERS is mutating, trigger/function may not see it
ORA-06512: at "ADMIN_BF.BALANCE_FEE", line 9
ORA-04088: error during execution of trigger 'ADMIN_BF.BALANCE_FEE'

这到底是什么问题?这与我的触发器是“插入后”有关吗? 预先感谢。

oracle triggers oracle-sqldeveloper mutating-table
2个回答
0
投票

您无法从当前正在更新的表中进行选择,因为它正在“变异”。不要使用

SELECT
语句,而是执行以下操作:

acl_date := :new.acl_return_date;
exp_date := :new.exp_return_date;
grp_id   := :new.grp_id;

之后剩下的代码应该没问题了。


0
投票

创建或替换触发器 trg_Facturation1_UID 在制造时插入、更新或删除之后1 对于每一行 宣布 v_count NUMBER; 开始 如果插入则 选择 COUNT(*) INTO v_count 从制造 WHERE FacturationId = :NEW.FacturationId; 如果 v_count = 0 那么 插入 Facturation(FacturationId、TransportId、DateFacture、MontantFacture、MontantRglt、DateRglt、ModeRglt、UserDateTDWH、UserNameDWH) VALUES(:NEW.FacturationId, :NEW.TransportId, :NEW.DateFacture, :NEW.MontantFacture, :NEW.MontantRglt, :NEW.DateRglt, :NEW.ModeRglt, TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS'),USER); 万一; 如果结束;

IF UPDATING THEN
    INSERT INTO Facturation(FacturationId, TransportId, DateFacture, MontantFacture, MontantRglt, DateRglt, ModeRglt,  UserDateTDWH, UserNameDWH)
    VALUES(:NEW.FacturationId, :NEW.TransportId, :NEW.DateFacture, :NEW.MontantFacture, :NEW.MontantRglt, :NEW.DateRglt, :NEW.ModeRglt, TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS'),USER);
END IF;

IF DELETING THEN
    INSERT INTO Facturation(FacturationId, TransportId, DateFacture, MontantFacture, MontantRglt, DateRglt, ModeRglt,  UserDateTDWH, UserNameDWH)
    VALUES(:OLD.FacturationId, :OLD.TransportId, :OLD.DateFacture, :OLD.MontantFacture, :OLD.MontantRglt, :OLD.DateRglt, :OLD.ModeRglt, TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS'), USER);
END IF;

结束; /

© www.soinside.com 2019 - 2024. All rights reserved.