在數據庫的觸發器中常常會用到更新前的值和更新後的值,全部要理解new和old的做用很重要。當時我有個狀況是這樣的:我要插入一行數據,在行要去其餘表中得到一個單價,而後和這行的數據進行相乘的到總金額,將該行的金額替換成相乘的結果。sql
一開始我使用的after,而後對自身的值進行更改。數據庫
insert | update | delete | |
---|---|---|---|
old | null | 實際值 | 實際值 |
new | 實際值 | 實際值 | null |
在Oracle中用:old
和:new
表示執行前的行,和執行後的行。在MySQL中用old
和new
表示執行前和執行後的數據。this
以前對數據庫的觸發器是這樣寫的,spa
1 CREATE TRIGGER triggerName after insert ON consumeinfo 2 FOR EACH ROW 3 BEGIN 4 UPDATE consumeinfo SET new.金額=0; 5 END;
觸發器建立沒問題,可是插入數據出現如下錯誤。code
[Err] 1442 - Can't update table 'consumeinfo' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
可是經過上網搜索的結果說對本表進行修改不用使用update consumeinfo
,直接使用SET new.金額=0
。這個作法對的,由於這樣使用new先對當前的金額改變了,而後存到數據庫中的,不用使用update consumeinfo。blog
通過一番努力,如下是成功後的代碼,貼出來看看ci
CREATE TRIGGER addnewReco BEFORE INSERT ON consumeinfo FOR EACH ROW BEGIN SET new.金額 = ( SELECT `單價` FROM pricenow WHERE `類型` = new.類型 ) * new.數量; END;
後來在吃飯打湯喝的時候忽然想到new和old在after和before上使用狀況不一樣。其實仍是由於new不能在after進行賦值,只能進行讀取,複製要在before時賦值。it
下面具體說說old和new的使用狀況。在對new賦值的時候只能在觸發器before中只用,在after中是不能使用的,好比(如下是正確的)。io
CREATE TRIGGER updateprice BEFORE insert ON consumeinfo FOR EACH ROW BEGIN set new.金額=0; END;
這個說明對當前插入數據進行更新的時候使用before先更新完,而後才插入到數據庫中的,在after的觸發器中,new的賦值已經結束了,只能讀取內容。 若是使用after不能使用new賦值,只能取值,不然會出錯誤,好比table
1 CREATE TRIGGER updateprice 2 AFTER insert 3 ON consumeinfo 4 FOR EACH ROW 5 BEGIN 6 set new.金額=0; 7 END;
出現這樣的錯誤:
[Err] 1362 - Updating of NEW row is not allowed in after trigger
|
|
總結:new在before觸發器中賦值,取值;在after觸發器中取值。old在用於取值?由於賦值沒意義?