Можно ли сравнить другие таблицы в триггере? - PullRequest
0 голосов
/ 08 июня 2011

У меня есть база данных с таблицами, которые связаны между собой внешними ключами, и последний в цепочке также имеет внешний ключ к себе.Я хочу удалить их с включенным каскадом, за исключением последнего в цепочке.Этот должен быть установлен в нуль, если его родительская запись не имеет определенного значения.Я подумал, что сделаю это с помощью триггера: всякий раз, когда последняя таблица обновлялась, если для внешнего ключа было установлено значение null, проверьте поле в родительской записи, а если это значение «default», удалите запись впоследний стол

Однако в Интернете я не нашел никакой справки о том, что сравниваются родительские записи в другой таблице.

Возможно ли это?

Ответы [ 2 ]

3 голосов
/ 08 июня 2011

Как правило, триггер уровня строки в таблице A не может запрашивать таблицу A. В этом случае обычно возникает исключение изменяющейся таблицы (ORA-04091).Поэтому триггер, как правило, не является правильным решением.

Предположительно, у вас есть какой-то API (то есть хранимая процедура) для удаления записей из родительской таблицы.Этот API должен запросить эту последнюю таблицу перед выдачей DELETE для родительской таблицы.Следует позаботиться об обновлении последней таблицы в цепочке, а также об удалении данных из родительской таблицы.

Если бы вы действительно хотели решение на основе триггера, жизнь стала бы значительно более сложной.Вы можете обойти исключительную ситуацию изменяющейся таблицы с помощью

  • Создание пакета с набором первичных ключей из родительской таблицы
  • Создание триггера оператора before, который инициализирует эту коллекцию
  • Создание триггера уровня строки, который заполняет коллекцию первичными ключами, которые были изменены оператором SQL
  • Создание триггера оператора after, который выполняет итерацию по коллекции и выдает все, что необходимо для DML (в отличие от уровня строкитриггеры, триггеры уровня оператора в таблице A могут запрашивать или изменять таблицу A).

Если вы используете 11g, вы можете немного упростить это с помощью составного триггера с оператором before, после строки,и после утверждения разделов.Но у вас еще есть несколько движущихся частей, чтобы попытаться скоординировать.

1 голос
/ 08 июня 2011

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

create or replace trigger last_table_trig
before update on last_table
for each row
declare
  l_parentField varchar2(100);
begin
  if :new.self_ref_fk is null then
     select p.parent_field into l_parentField from parent_table p
     where p.pk = :new.parent_fk;
     if l_parentField = 'default' then
       :new.status := 'DELETED';
     end if;
  end if;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...