簡體   English   中英

在同一張表上插入觸發器后更新

[英]Update with after insert trigger on same table

我要在tableA上寫一個插入觸發器。 它將使用相同的表但不同的列執行更新。 執行此操作時出現錯誤。 我的觸發器是

create or replace trigger trigger_A
after insert on table_A
begin
  update table_A set col1=1 where col1 is null;
end;

我有一個應用程序將單獨執行col2並將col1保持為空。 因此,一旦插入行,我的觸發器將為col1提供值。 但是插入行時出現錯誤消息,提示“觸發器失敗且無效”。 這個怎么做。 TIA。

如果要分配一個簡單的默認值,最簡單的方法是使用DEFAULT子句在表上聲明它。

SQL> create table t42
  2    ( col1 number default 1 not null
  3      , col2 date)
  4  /

Table created.

SQL> insert into t42 (col2) values (sysdate)
  2  /

1 row created.

SQL> select * from t42
  2  /

      COL1 COL2
---------- ---------
         1 03-AUG-11

SQL>

這適用於文字或偽列,例如SYSDATE或USER。 如果要使用用戶定義的函數或序列派生更復雜的值,則需要使用觸發器。

這是表格的新版本...

SQL> create table t42
  2    ( col1 number default 1 not null
  3      , col2 date default sysdate
  4      , col3 varchar2(30) default user
  5      , col4 number )
  6  /

Table created.

SQL>

...帶有觸發器:

SQL> create or replace trigger t42_trg
  2      before insert or update
  3      on t42
  4      for each row
  5  begin
  6      if :new.col4 is null
  7      then
  8          :new.col4 := my_seq.nextval;
  9      end if;
 10  end;
 11  /

Trigger created.

SQL> insert into t42 (col1, col2, col3)
  2  values (99, sysdate, 'MR KNOX')
  3  /

1 row created.

SQL> select * from t42
  2  /

      COL1 COL2      COL3                                 COL4
---------- --------- ------------------------------ ----------
        99 03-AUG-11 MR KNOX                               161

SQL>

請注意,盡管表上的每一列都是默認列,但我必須填充至少一列以使SQL有效:

SQL> insert into t42 values ()
  2  /
insert into t42 values ()
                        *
ERROR at line 1:
ORA-00936: missing expression


SQL>

但是我可以將NULL傳遞給COL4以獲得完全默認的記錄:

SQL> insert into t42 (col4) values (null)
  2  /

1 row created.

SQL> select * from t42
  2  /

      COL1 COL2      COL3                                 COL4
---------- --------- ------------------------------ ----------
        99 03-AUG-11 MR KNOX                               161
         1 03-AUG-11 APC                                   162

SQL>

警告:我的觸發器使用了新的11g語法。 在以前的版本中,我們必須使用SELECT語句分配序列值:

select my_seq.nextval
into :new.col4
from dual;

您不能更新調用觸發器的表:

在存儲的函數或觸發器中,不允許修改調用該函數或觸發器的語句已經在使用(用於讀取或寫入)的表。

這樣做會生成錯誤1442:

Error Code: 1442
Can't update table 'MyTable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

簡而言之,我們不允許更新使用中的表-但您的情況很簡單,如果字段為NULL,則只想更新該字段,為此,請選擇BEFORE INSERT ON觸發器,這樣您就可以更新new /當前條目/行(因為尚未輸入):

DELIMITER //
DROP TRIGGER IF EXISTS trigger_A//
CREATE TRIGGER trigger_A BEFORE INSERT ON table_A
FOR EACH ROW BEGIN
    IF NEW.col1 IS NULL THEN
        set NEW.col1 = <some-value>;
    ENF IF;
END;
//
DELIMITER ;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM