Простые оракулы - PullRequest
       30

Простые оракулы

0 голосов
/ 13 сентября 2010

Простой. Я новичок в 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'

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

ура

е.

Ответы [ 2 ]

5 голосов
/ 13 сентября 2010

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

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

Поскольку вы можете изменять только НОВЫЕ значения в before-each-триггеры строк:

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.

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

2 голосов
/ 13 сентября 2010

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

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;
...