Где происходит мутация таблицы (Oracle)? - PullRequest
0 голосов
/ 20 апреля 2020

Я сейчас имею дело с oracle SQL и пытаюсь создать триггер. По какой-то причине он показывает мне ошибку мутированной таблицы, однако, я не вижу, где она вообще видоизменяется (это просто выбор без четных отсчетов, однако, он имеет соединения). С чего мне хотя бы начать писать составной триггер для решения? Кажется, есть только несколько примеров, и они слишком далеки от моего, чтобы понять, как это вообще должно работать в данной конкретной ситуации.

  CREATE OR REPLACE TRIGGER "EVGENIJ_BOBROVICH"."FIX_UPD_LIMITS" 
BEFORE UPDATE OR DELETE ON "EVGENIJ_BOBROVICH"."MAP_CALCULATION_SHOP_LIMITS"
FOR EACH ROW
DECLARE
is_deleted_dependant VARCHAR2(1 BYTE);
is_editable_dependant VARCHAR2(1 BYTE);
BEGIN
SELECT IS_DELETE, IS_EDITABLE INTO is_deleted_dependant, is_editable_dependant
FROM MAP_CALCULATION MC INNER JOIN map_calculation_group MG
ON MC.ID_CALC = MG.ID_CALC INNER JOIN map_calculation_shop_limits MS ON MG.ID_GROUP = ms.id_group
WHERE :OLD.ID_GROUP = MG.ID_GROUP AND MG.ID_CALC = MC.ID_CALC;
IF UPDATING AND (is_editable_dependant = 'F' OR is_deleted_dependant = 'T') THEN
RAISE_APPLICATION_ERROR( -20004, '....Error......' );   
ELSIF DELETING AND (is_editable_dependant = 'F' OR is_deleted_dependant = 'T') THEN
RAISE_APPLICATION_ERROR( -20005, '...AnotherError...' );   
END IF;
END;
/

Сам выбор без триггера (без входного и старого конечно же, я использовал переменную связывания вместо старой) отлично работает ...

1 Ответ

1 голос
/ 20 апреля 2020

Это происходит здесь:

INNER JOIN map_calculation_shop_limits

Вы не можете выбрать из той же таблицы, что обновляете, как есть ... ну, мутирует .

Для целей обновления вы должны

 FROM map_calculation mc
      INNER JOIN map_calculation_group mg ON mc.id_calc = mg.id_calc
      -- INNER JOIN map_calculation_shop_limits MS ON MG.ID_GROUP = ms.id_group       --> this
WHERE     :old.id_group = mg.id_group
      AND mg.id_calc = mc.id_calc
      AND mg.id_group = :new.id_group;          --> and this

Для удаления вы должны использовать :old.id_group, что означает, что вам нужно будет переписать используемый код на две части: одна, которая будет обрабатывать обновления, и еще один для обработки удаляет.

...