2010-09-13 5 views
0

Простой. Я немного newvbie с PLSql, и сообщения об ошибках oracle никогда не слишком полезны.Простые триггеры оракула

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

Идея проста

create table test1 (tcol varchar2(255), tcol2 varchar2(255)) 

CREATE OR REPLACE TRIGGER testTRG 
AFTER INSERT OR UPDATE ON test1 
FOR EACH ROW 
BEGIN 
    update test1 
    set tcol2 = to_char(sysdate) 
    where tcol = :OLD.tcol; 
END; 

insert into test1 (tcol) values ('test1'); 

это выскакивает ошибка:

ORA-04091: table RAIDBIDAT_OWN.TEST1 is mutating, trigger/function may not see it 
ORA-06512: at "RAIDBIDAT_OWN.TESTTRG", line 2 
ORA-04088: error during execution of trigger 'RAIDBIDAT_OWN.TESTTRG' 

ли кто-нибудь есть быстрое решение для этого?

cheers,

f.

+0

Поскольку вы сказали, что таблица имеет varchar для столбца назначения, я бы рекомендовал делать 'to_char (sysdate, ', то есть 'to_char (sysdate, 'YYYY-MM-DD HH24: Mi: SS') ', чтобы быть явным в отношении формата сохраняемой даты, вместо implicilty, принимающего' NLS_DATE_FORMAT', который может быть другим для разных сеансов. –

ответ

5

Ваша ситуация:

SQL> create table test1 (tcol varchar2(255), tcol2 varchar2(255)) 
    2/

Table created. 

SQL> CREATE OR REPLACE TRIGGER testTRG 
    2 AFTER INSERT OR UPDATE ON test1 
    3 FOR EACH ROW 
    4 BEGIN 
    5  -- Your original trigger 
    6  update test1 
    7  set tcol2 = to_char(sysdate) 
    8  where tcol = :OLD.tcol; 
    9 END; 
10/

Trigger created. 

SQL> insert into test1 (tcol) values ('test1'); 
insert into test1 (tcol) values ('test1') 
      * 
ERROR at line 1: 
ORA-04091: table [schema].TEST1 is mutating, trigger/function may not see it 
ORA-06512: at "[schema].TESTTRG", line 3 
ORA-04088: error during execution of trigger '[schema].TESTTRG' 

предложение Тони почти сразу же, но, к сожалению, он не компилируется:

SQL> CREATE OR REPLACE TRIGGER testTRG 
    2 AFTER INSERT OR UPDATE ON test1 
    3 FOR EACH ROW 
    4 BEGIN 
    5  -- Tony's suggestion 
    6  :new.tcol2 := sysdate; 
    7 END; 
    8/
CREATE OR REPLACE TRIGGER testTRG 
          * 
ERROR at line 1: 
ORA-04084: cannot change NEW values for this trigger type 

Поскольку вы можете изменять только НОВЫЕ значения в триггерах перед каждой строкой:

SQL> create or replace trigger testtrg 
    2 before insert or update on test1 
    3 for each row 
    4 begin 
    5 :new.tcol2 := sysdate; 
    6 end; 
    7/

Trigger created. 

SQL> insert into test1 (tcol) values ('test1'); 

1 row created. 

SQL> select * from test1 
    2/

TCOL 
------------------------------------------------------------------------------------------ 
TCOL2 
------------------------------------------------------------------------------------------ 
test1 
13-09-2010 12:37:24 


1 row selected. 

С уважением, Роб.

+0

, это здорово. работает как шарм! Большое спасибо. – filippo

2

Триггер должен просто читать:

CREATE OR REPLACE TRIGGER testTRG 
BEFORE INSERT OR UPDATE ON test1 
FOR EACH ROW 
BEGIN 
    :new.tcol2 := to_char(sysdate); 
END; 

Там нет требования, чтобы выпустить еще одно обновление одного и того же ряда (и, как вы обнаружили, вы не можете).

Это более привычно использовать DATE столбцы для хранения дат:

create table test1 (tcol varchar2(255), tcol2 date); 

CREATE OR REPLACE TRIGGER testTRG 
BEFORE INSERT OR UPDATE ON test1 
FOR EACH ROW 
BEGIN 
    :new.tcol2 := sysdate; 
END; 
+0

ar u sure thats sintax? получил это сейчас: 2/17 PLS-00103 : Встречается символ «=» при ожидании одного из следующих значений: : =. (@%; Индикатор 3/1 PLS-00103: встречается символ «END» – filippo

+0

о, и о дате. Я согласен с вы, просто случается, что фактическая таблица имеет varchar для этого столбца, и я не могу изменить ее по другим причинам, но спасибо :) – filippo

+0

oh .. Я скопировал первое редактирование. g ":". извините за мой newbnes :( – filippo