2011-08-03 154 views
1

我有一個在表A上寫入插入觸發器。它將使用同一個表但不同的列執行更新。我在做這件事時遇到了錯誤。我的觸發器是在同一個表上插入觸發器後更新

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。

+0

首先,嘗試'Col1 IS NULL'。 * NOTHING *等於('=')NULL,甚至不是NULL。雖然我不相信這是你錯誤的根源。 – MatBailie

+0

@Dems - 更改我的代碼! – Navin

回答

6

如果您想分配一個簡單的默認值,最簡單的方法是使用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以獲得完全的defa ulted記錄:

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> 

買者講師:我的觸發使用新11克語法。在以前的版本中,我們必須使用SELECT語句來分配序列值:

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

不能更新,其中觸發器被調用的表:

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

這樣做將產生錯誤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觸發器,這樣您可以更新新/當前條目/行的所有字段(因爲它尚未輸入):

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 ; 
相關問題