2013-12-17 4 views
0

У меня есть две таблицы main и hist. Я хочу скопировать строку из таблицы main всякий раз, когда ее столбец datetime был изменен на hist и сбросил измененные столбцы в main до null, за исключением одного столбца. Однако я получаю мутирующую ошибку запуска. Пожалуйста помоги. Ниже приведены два триггера,Mutating Trigger Oracle

CREATE OR REPLACE TRIGGER INS_HIS 
AFTER UPDATE OF datetime ON main 
FOR EACH ROW 
    INSERT INTO HIST 
    VALUES (Col2 = :new.col2, Col3= :new.Col3) 
END; 


CREATE OR REPLACE TRIGGER UPD_NUL_MAIN 
AFTER INSERT ON HIST 
FOR EACH ROW 
    UPDATE Main 
     SET (Col2 = NULL 
      Col3= NULL) 
    WHERE HIST.datetime = main.datetime; 
END 
+0

Эй Роб, я думаю, что ошибка с второго триггера, столбцы копируются чужого стола, но после этого, когда он должен сделать основные столбцы обнулить он не работает , – user3110283

+0

Yep - Я видел ошибку моих путей (я не заметил ПОСЛЕ ОБНОВЛЕНИЯ времени) и удалил исходный комментарий. –

ответ

2

Предполагая, что вы хотите изменить только строку в основном, что инициировало обновление, вы можете избавиться от второго триггера в целом, если вы измените свой первый триггер на BEFORE UPDATE один и установить col2 и col3 там:

CREATE OR REPLACE TRIGGER INS_HIS 
BEFORE UPDATE OF datetime ON main 
FOR EACH ROW   
BEGIN 
    INSERT INTO HIST 
    (col2, 
    col3) 
    VALUES 
    (:new.col2, 
    :new.Col3); 
    :new.col2 := NULL; 
    :new.col3 := NULL; 
END; 

КСТАТИ: ваш синтаксис запуска неправильно - вы не можете использовать (col2 =: new.col2).

+0

Извинения - отвлекшись во время написания сообщения, и похоже, что я представил дубликат ответа! –

+0

Нет проблем, случается со мной все время :-) –

+0

ohh yeah ur right abt синтаксис, мой плохой, но нулевая вещь в том же триггере не произойдет – user3110283

1

Для этого я думаю, что вам нужен только один триггер?

CREATE OR REPLACE TRIGGER ins_his BEFORE UPDATE OF datetime ON main 
FOR EACH ROW 
BEGIN 

    INSERT INTO hist (col2  , col3  ) 
      VALUES (:new.col2, :new.col3); 

    :new.col2 := NULL; 
    :new.col3 := NULL; 

END; 
/

Пример вывода:

SQL*Plus: Release 11.2.0.1.0 Production on Tue Dec 17 13:17:08 2013 

Copyright (c) 1982, 2010, Oracle. All rights reserved. 


Connected to: 
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production 
With the Partitioning, Real Application Clusters, Automatic Storage Management, 
OLAP, 
Data Mining and Real Application Testing options 

SQL> create table main (datetime DATE, col2 NUMBER, col3 NUMBER); 

Table created. 

SQL> create table hist (col2 NUMBER, col3 NUMBER); 

Table created. 

SQL> CREATE OR REPLACE TRIGGER ins_his BEFORE UPDATE OF datetime ON main 
    2 FOR EACH ROW 
    3 BEGIN 
    4 -- 
    5 INSERT INTO hist (col2  , col3  ) 
    6    VALUES (:new.col2, :new.col3); 
    7 -- 
    8 :new.col2 := NULL; 
    9 :new.col3 := NULL; 
10 -- 
11 END; 
12/

Trigger created. 

SQL> insert into main(datetime, col2, col3) 
    2 values (sysdate, 5, 10); 

1 row created. 

SQL> select * from main; 

DATETIME  COL2  COL3 
--------- ---------- ---------- 
17-DEC-13   5   10 

SQL> select * from hist; 

no rows selected 

SQL> update main set datetime = sysdate-1; 

1 row updated. 

SQL> select * from main; 

DATETIME  COL2  COL3 
--------- ---------- ---------- 
16-DEC-13 

SQL> select * from hist; 

     COL2  COL3 
---------- ---------- 
     5   10 

SQL> 
+0

Вы уверены, что это работает с триггером AFTER UPDATE (вместо ПЕРЕД ОБНОВЛЕНИЕМ)? –

+0

Ahh Я не думаю, что мы можем изменить значения на null в одном и том же триггере. Это не произойдет, потому что событие находится на главной таблице – user3110283

+0

Как и в случае с приведенным выше ответом. Вы на самом деле * попробовали * это? –