Таблица ORA-04091 * видоизменяется, триггер / функция может ее не видеть

#oracle #triggers #oracle-sqldeveloper #mutating-table

#Oracle #триггеры #oracle-sqldeveloper #изменение-таблица

Вопрос:

Я работаю над проектом, который сдает лодки в аренду клиентам и на основе введенной ими информации предоставляет им лодку. В одном из разделов этого проекта я хочу создать триггер, который на основе того, когда вы уходите с лодкой, и когда вы возвращаетесь, он будет вычислять дни, а затем либо возвращать деньги на баланс клиента, либо взимать дополнительную плату. У меня есть настройка триггера следующим образом —

 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'
 

В чем именно здесь проблема? Это как-то связано с тем, что мой триггер является «После вставки»?
Заранее спасибо.

Ответ №1:

Вы не можете выбрать из таблицы, которая обновляется прямо сейчас, поскольку она «видоизменяется». Вместо SELECT инструкции сделайте это:

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

После этого остальная часть кода должна быть в порядке.

Комментарии:

1. Я ценю помощь. Я столкнулся с другой ошибкой, которая теперь, вероятно, связана с вычитанием даты. Может быть, вы тоже можете помочь мне разобраться с этой проблемой. ВСТАВИТЬ В УСТАВЫ (CHARTER_ID, BOAT_ID, EXP_RETURN_DATE,ACL_RETURN_DATE,GRP_ID) ЗНАЧЕНИЯ (‘T003′,’B003’,ДАТА ‘2019-05-5’,ДАТА ‘2019-05-07′,’G003’) Отчет об ошибке — ORA-06502: PL / SQL: числовая ошибка или ошибка значения: ошибка преобразования символа в число ОРА-06512: в «ADMIN_BF.BALANCE_FEE», строка 11 ORA-04088: ошибка во время выполнения триггера «ADMIN_BF.BALANCE_FEE»

2. Литерал ДАТЫ должен быть в формате ГГГГ-ММ-ДД; первое, которое вы опубликовали, нет (должно быть 05, а не 5). При вычитании двух значений ДАТЫ результатом является КОЛИЧЕСТВО дней между ними, так что это не должно быть проблемой.

3. Я только что исправил эту проблему, но я все еще получаю ее. ВСТАВИТЬ В УСТАВЫ (CHARTER_ID, BOAT_ID, EXP_RETURN_DATE,ACL_RETURN_DATE,GRP_ID) ЗНАЧЕНИЯ (‘T003′,’B003’,ДАТА ‘2019-05-05’,ДАТА ‘2019-05-07′,’G003’) Отчет об ошибке — ORA-06502: PL / SQL: числовая ошибка или ошибка значения: ошибка преобразования символа в число ОРА-06512: в «ADMIN_BF.BALANCE_FEE», строка 11 ORA-04088: ошибка во время выполнения триггера «ADMIN_BF.BALANCE_FEE»

4. Какая строка является строкой # 11?

5. Строка 11 — это строка прямо перед ACL_DATE := :NEW.ACL_RETURN_DATE;