Подзапрос Oracle to_char в триггере

У меня есть таблица (Meeting) с атрибутом типа даты (MeetDate) и другим атрибутом типа varchar2 (WorkWeek). Я пытаюсь сделать триггер After, чтобы заполнить поле WorkWeek на основе значения MeetDate, используя функцию to_char. Пробовал следующие коды отдельно, и они компилируются без ошибок, но когда я пытаюсь вставить строку с Null для WorkWeek, это дает мне ошибку «мутирующий триггер/функция может не видеть его». Что я здесь делаю неправильно? заранее спасибо за любую помощь.

--Code 1
Create or Replace Trigger Update_WorkWeek
After Insert On Meeting
For Each Row
Begin
Update Meeting
Set WorkWeek  = (Select to_char(:new.MeetDate, 'YYYY IW') From Dual)
Where MeetID = :new.MeetID;
End;
/
show Errors;

--Code 2
Create or Replace Trigger Update_WorkWeek
After Insert On Meeting
For Each Row
Begin
if :New.WorkWeek is Null then
Update Meeting
Set WorkWeek  = (Select to_char(:new.MeetDate, 'YYYY IW') From Dual)
Where MeetID = :new.MeetID;
End if;
End;
/
show Errors;

person Nimesh Wicks    schedule 01.05.2013    source источник
comment
Я не понимаю, зачем вам нужен второй триггер, который, вероятно, является причиной ошибки изменяющихся таблиц. Второй триггер просто проверяет нулевую рабочую неделю и делает то же самое, что и первый триггер. Если я что-то упускаю, можете ли вы объяснить, зачем вам нужен второй триггер.   -  person ron tornambe    schedule 01.05.2013
comment
Я использовал их отдельно. Я пробовал оба по отдельности, но ни один из них не работает. выдает ту же ошибку.   -  person Nimesh Wicks    schedule 01.05.2013
comment
Я также пытался использовать тот же триггер, используя «До» вместо «После». Когда я сделал это и вставил строку с Null для WorkWeek, она просто не заполнила поле для этой записи. Но не получил мутирующей ошибки.   -  person Nimesh Wicks    schedule 01.05.2013
comment
Есть ли способ объявить это в DDL при создании таблицы как ограничение для атрибута?   -  person Nimesh Wicks    schedule 01.05.2013
comment
Я не думаю, что вам нужен оператор UPDATE, если вы только присваиваете новое значение WorkWeek. Попробуйте просто установить :new.WorkWeek = (Select to_char(:new.MeetDate, 'YYYY IW') From Dual), где MeetID = :new.MeetID; - удалить обновление встречи   -  person ron tornambe    schedule 01.05.2013
comment
Нет. Вы не можете объявить значение по умолчанию для ссылки на столбец. docs.oracle.com/cd/E11882_01/server.112/ e17118/   -  person ron tornambe    schedule 01.05.2013
comment
При этом я получил следующую ошибку: 15 февраля PLS-00103: Обнаружен символ = при ожидании одного из следующих: := . ( @ % ; индикатор 3/1 PLS-00103: Обнаружен символ WHERE при ожидании одного из следующих: ; return return and или 4/1 PLS-00103: Обнаружен символ END   -  person Nimesh Wicks    schedule 01.05.2013
comment
Я думаю, что правильный синтаксис: Select to_char(:new.MeetDate, 'YYYY IW') в :new.WorkWeek; Это будет единственная инструкция в триггере BEFORE INSERT.   -  person ron tornambe    schedule 01.05.2013


Ответы (1)


Вы просто хотите, чтобы триггер изменил значение столбца до того, как он будет вставлен, и он находится в той же строке, поэтому вам не нужно ОБНОВЛЕНИЕ:

Create or Replace Trigger Update_WorkWeek
BEFORE Insert On Meeting
For Each Row
Begin
  :new.WorkWeek := to_char(:new.MeetDate, 'YYYY IW');
End;
/
show Errors;

Возможно, вы захотите, чтобы столбец обновлялся, если MeetDate изменяется, т.е.:

Create or Replace Trigger Update_WorkWeek
BEFORE Insert
    OR Update OF MeetDate
On Meeting
For Each Row
Begin
  :new.WorkWeek := to_char(:new.MeetDate, 'YYYY IW');
End;
/
show Errors;
person Jeffrey Kemp    schedule 01.05.2013
comment
Спасибо Джеффри! Это прекрасно работает. Логически говоря, вставляет ли Oracle сначала значение WorkWeek перед заполнением других атрибутов для этой строки? - person Nimesh Wicks; 01.05.2013
comment
Нет, триггер BEFORE позволяет изменить строку (так сказать, в памяти) до того, как она будет вставлена. Затем строка вставляется, после чего срабатывает триггер AFTER (и тогда уже слишком поздно его менять). - person Jeffrey Kemp; 01.05.2013