Попытка удалить строку на основе условия, определенного в моем триггере (SQL) - PullRequest
0 голосов
/ 27 июня 2019

Я пытаюсь создать триггер на уровне строки, чтобы удалить строку, если значение в строке становится равным NULL.Мои бизнес-параметры утверждают, что если значение становится нулевым, то строка должна быть удалена.Также я не могу использовать глобальную переменную.

BEGIN
  IF :NEW.EXHIBIT_ID IS NULL THEN
   DELETE SHOWING
   WHERE EXHIBIT_ID = :OLD.EXHIBIT_ID;
  END IF;

Я получаю следующие ошибки:

ORA-04091: table ISA722.SHOWING is mutating, trigger/function may not see it
ORA-06512: at "ISA722.TRG_EXPAINT", line 7
ORA-04088: error during execution of trigger 'ISA722.TRG_EXPAINT'

При выполнении этого запроса:

UPDATE SHOWING
  SET EXHIBIT_ID = NULL
WHERE PAINT_ID = 5104

Ответы [ 3 ]

0 голосов
/ 28 июня 2019

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

Таким образом, вместо этого вы должны написать триггер оператора после, который срабатывает только при выполнении всего оператора.

create or replace trigger mytrigger
after update of exhibit_id on showing 
begin
  delete from showing where exhibit_id is null;
end mytrigger;

Демо: https://dbfiddle.uk/?rdbms=oracle_18&fiddle=dd5ade700d49daf14f4cdc71aed48e17

0 голосов
/ 28 июня 2019

Что вы можете сделать, это создать дополнительный столбец, такой как is_to_be_deleted в той же таблице, и сделать это:

UPDATE SHOWING SET EXHIBIT_ID = NULL, is_to_be_deleted = 'Y' WHERE PAINT_ID = 5104;

Вы можете использовать этот параметр для реализации своей бизнес-логики непоказывая нулевые детали.

И позже вы можете запланировать пакетное удаление в этой таблице, чтобы очистить эти строки (или, возможно, заархивировать их).Преимущество: вы можете избежать лишних триггеров для этой таблицы.

Никто не предложит вам использовать триггер для удаления этого типа, так как это дорого.

0 голосов
/ 28 июня 2019

Как уже указывалось, это ужасная идея / дизайн.Триггеры - очень плохие методы для обеспечения соблюдения бизнес-правил.Они должны применяться в приложении или лучше (IMO) с помощью хранимой процедуры, вызываемой приложением.В этом случае это не только плохая идея, но и не может быть реализовано по желанию.Внутри триггера Oracle не разрешает доступ к таблице, по которой сработал триггер.Это то, что указывает на мутирование.Подумайте о попытке отладить это или решить проблему неделю спустя.Тем не менее, это бессмысленное может быть достигнуто путем создания представления и обработки вместо него вместо таблицы.

-- setup 
create table showing (exhibit_id integer, exhibit_name varchar2(50));
create view show as select * from showing;
-- trigger on VIEW
create or replace trigger show_iiur
    instead of insert or update on show 
    for each row 
begin 
    merge into showing 
         using (select :new.exhibit_id new_eid
                     , :old.exhibit_id old_eid 
                     , :new.exhibit_name new_ename
                  from dual
               ) on (exhibit_id = old_eid)
         when matched then 
              update set exhibit_name = new_ename
              delete where new_eid is null
         when not matched then
              insert (exhibit_id, exhibit_name)
              values (:new.exhibit_id, :new.exhibit_name);
end ;
-- test data
 insert into show(exhibit_id, exhibit_name)
   select 1,'abc' from dual union all 
   select 2,'def' from dual union all
   select 3,'ghi' from dual; 
-- 3 rows inserted

select * from show;

--- test 
update show 
   set exhibit_name = 'XyZ'
 where exhibit_id = 3;
-- 1 row updated

-- Now for the requested action. Turn the UPDATE into a DELETE
 update show
    set exhibit_id = null 
  where exhibit_name = 'def'; 
-- 1 row updated

select * from show;

-- table and view are the same (expect o rows)
select * from show MINUS select * from showing
UNION ALL
select * from showing MINUS select * from show;

Опять же, это плохой вариант, но вы можете это сделать.Но только потому, что вы можете, не значит, что вы должны.Или что вы будете довольны результатом.Удачи.

...