Вопрос по sql – Создание триггера, который удаляет строку, когда атрибут становится отрицательным [оракул sql]?

1

Я хотел бы создать триггер, который удалит строку, когда один из ее атрибутов станет отрицательным. Пока у меня есть это, но это не похоже на действительный sql:

<code>CREATE OR REPLACE TRIGGER ZERO_COPIES_TRIGGER
after
update of counter_attribute
on my_table
referencing new as new
for each row when(new.copies < 0)
begin
  delete from my_table where my_table.id = :new.id;
end;
</code>

Ваш Ответ

2   ответа
5

которой манипулирует триггер на уровне строк. Вы получите «мутирующую таблицу» ошибка.

Чтобы получить желаемый результат, лучше всего иметь столбец флага или индикатора, чтобы определить, что записьto be deleted, Затем создайте отдельное задание или процесс или еще что-нибудь, чтобы фактически выполнить удаление.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
3

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

CREATE OR REPLACE TRIGGER ZERO_COPIES_TRIGGER
      AFTER UPDATE OF COUNTER_ATTRIBUTE ON MY_TABLE
BEGIN
  FOR aROW IN (SELECT ID
                 FROM MY_TABLE
                 WHERE COPIES < 0)
  LOOP
    DELETE FROM MY_TABLE
      WHERE ID = aROW.ID;
  END LOOP;
END ZERO_COPIES_TRIGGER;

Или, если выreally Если вы хотите повеселиться, вы можете использовать составной триггер для обработки удалений, не требуя сканирования таблицы, при этом избегая страшного & quot; MUTATING TABLE & quot; ошибка, как в:

CREATE OR REPLACE TRIGGER COMPOUND_ZERO_COPIES_TRIGGER
  FOR UPDATE OF COUNTER_ATTRIBUTE ON MY_TABLE
COMPOUND TRIGGER
  TYPE NUMBER_TABLE IS TABLE OF NUMBER;
  tblDELETE_IDS  NUMBER_TABLE;

  BEFORE STATEMENT IS
  BEGIN
    tblDELETE_IDS := NUMBER_TABLE();
  END BEFORE STATEMENT;

  AFTER EACH ROW IS
  BEGIN
    IF :NEW.COPIES < 0 THEN
      tblDELETE_IDS.EXTEND;
      tblDELETE_IDS(tblDELETE_IDS.LAST) := :NEW.ID;
    END IF;
  END AFTER EACH ROW;

  AFTER STATEMENT IS
  BEGIN
    IF tblDELETE_IDS.COUNT > 0 THEN
      FOR I IN tblDELETE_IDS.FIRST..tblDELETE_IDS.LAST LOOP
        DELETE FROM MY_TABLE
          WHERE ID = tblDELETE_IDS(I);
      END LOOP;
    END IF;
  END AFTER STATEMENT;
END COMPOUND_ZERO_COPIES_TRIGGER;

Поделитесь и наслаждайтесь.

Похожие вопросы