#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;