SQL при триггере удаления

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

  1 Create Or Replace Trigger cancel
  2 After Delete
  3         On OrderTable
  4         For EACH ROW
  5 Begin
  6         Insert Into CancelledOrders Values (:old.acctNum, age, phone)
  7         From OrderTable Natural Join Customer
  8         Where acctid = :old.acctNum AND menuid = :old.menuNum;
  9 End;
 10 /
 11 Show Errors;

Я хочу получить acctNum, age и phone. acctNum из таблицы Order, а age и phone из таблицы Customer. Поэтому я соединяю две таблицы (по ключу acctid). Таким образом, объединенный результат будет выглядеть так:

acctNum Age Phone

Я получаю эту ошибку, когда пытаюсь скомпилировать триггер:

2/2  PL/SQL: SQL Statement ignored
3/2  PL/SQL: ORA-00933: SQL command not properly ended

Кто-нибудь знает проблему?

EDIT: Структура таблицы:

Таблица заказов: AcctNum MenuNum startOrder endOrder
Таблица клиентов: AcctNum age phone


person Community    schedule 06.05.2016    source источник


Ответы (2)


Вы смешиваете синтаксис values и select (подзапрос)< /a>, которые предназначены для разных целей. Вы можете вставить из запроса, который использует значение из псевдозаписи :old и значения из таблицы клиентов:

    Insert Into CancelledOrders -- (acctNum, age, phone)
    Select :old.acctNum, age, phone
    From Customer
    Where acctNum = :old.acctNum;

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

person Alex Poole    schedule 06.05.2016
comment
В предложении where, где вы делаете :old.acctNum, относится только к таблице, из которой строки были удалены правильно? Он знает таблицу, из которой были удалены строки? - person ; 06.05.2016
comment
@ 1290 - :old относится к псевдозаписи, так как это триггер for each row. Таким образом, он будет использовать значение из удаляемой строки, да. Он не запрашивает эту таблицу напрямую. О, подождите, да, но этого не должно быть, мне нужно это исправить - можете ли вы добавить структуры таблиц к вопросу, чтобы я мог видеть, что исходит от каждого? - person Alex Poole; 06.05.2016
comment
О, теперь я вижу. Но поскольку я присоединился к таблицам, удаленная строка (из OrderTable) будет присоединена к другой строке в таблице клиентов. Таким образом, в основном old будет ссылаться на эту объединенную строку с удаленными значениями из таблицы заказов. - person ; 06.05.2016
comment
О, так мне не нужно Natural Join, так как я уже указал таблицу, из которой удаляется строка после строки After Delete? - person ; 06.05.2016
comment
Значит, естественное соединение было на acctNum? Я обновил, чтобы удалить это соединение, так как вам не нужно снова смотреть на orderTable. Я не знаю, где сидит menuNum, этого нет в вашем редактировании. Если он в orderTable, он вам тоже не нужен. - person Alex Poole; 06.05.2016
comment
Извините за это, я только что добавил menuNum, который находится в OrderTable. - person ; 06.05.2016
comment
Хорошо, отлично, я тоже убрал эту ссылку. Так что это довольно простое утверждение в конце *8-) - person Alex Poole; 06.05.2016

Ваш оператор вставки неверен. Вам нужно указать столбцы, которые вы хотите выбрать в таблицах.

Добавьте предложение select в оператор вставки. Кроме того, удалено ключевое слово values и указаны имена столбцов:

  Insert Into CancelledOrders (acctNum, age, phone)
  Select :old.acctNum, age, phone
  From OrderTable Natural Join Customer
  Where acctid = :old.acctNum AND menuid = :old.menuNum;
person Joel    schedule 06.05.2016