這是昨天做資料庫的時候遇到的乙個問題:
(更新本表造成觸發迴圈)
為了方便敘述,只列出部分屬性。
我有乙個關係模式
bbsuser(uid,uname,uclass,upointn)
uid : 使用者id
uname: 使用者名稱
ulevel: 使用者級別
upointn: 使用者積分
我給定乙個需求:
更新使用者積分upoint後,更新使用者等級。
等級規則如下:
等級 積分
1 0-500
2 500-1000
3 1000-2000
4 2000-4000
5 4000-6000
6 6000以上
看到這個我就會去想寫乙個觸發器來做這個事情,但是出現了意外。我的觸發器是這樣寫的。
create trigger auto_updatelevel
after update
on bbsuser
for each row
declare
upoint number;
x number;
begin
upoint:=:new.upointn;
if0<=upoint and upoint <500
then
x:=1;
elsif
500<=upoint and upoint <1000
then
x:=2;
elsif
1000
<=upoint and upoint <2000
then
x:=3;
elsif
2000
<=upoint and upoint <4000
then
x:=4;
elsif
4000
<=upoint and upoint <5000
then
x:=5;
elsif
5000
<=upoint then
x:=6;
endif; update bbsuser set upoint=upointn where "uid"=:new.uid;
end;
由於剛剛學習oracle,看起來是對的,實則錯誤太多太多。
以上**的問題所在,如果執行更新操作後觸發器會執行,觸發器內部又會執行更新操作,然後又會執行觸發器,觸發器又執行更新。這樣繼續下去就會造成死鎖的問題,而且觸發器還是無效的。原因就在在於更新的時候不對,不能有更新這個操作,更新應該通過賦值的方式來進行
--把上面的update語句變成這個
:new.ulevel:=x;--(賦值更新,但是錯誤的)
但是這樣還是錯誤的。因為我們更新時期是after,也就是在更新之後去賦值,但是更新操作已經結束,這個時候賦值還有什麼意義?
所以有了如下的解決方法。
create trigger auto_updatelevel
before update
on bbsuser
for each row
declare
upoint number;
x number;
begin
upoint:=:new.upointn;
if0<=upoint and upoint <500
then
x:=1;
elsif
500<=upoint and upoint <1000
then
x:=2;
elsif
1000
<=upoint and upoint <2000
then
x:=3;
elsif
2000
<=upoint and upoint <4000
then
x:=4;
elsif
4000
<=upoint and upoint <5000
then
x:=5;
elsif
5000
<=upoint then
x:=6;
endif; :new.ulevel:=x;
end;
對這個語句的解釋是:在更新本表之前得到要更新的upoint新值,對upoint的大小進行判斷來確定等級。然後將等級x賦值給:new.ulevel(將要更新的使用者等級),也就是提前改變了更新的值,所以在更新後的等級一定是乙個正確的結果。 mysql 更新本表觸發器
例項 create definer root trigger jq jq jam event t before update before update on jq jam event t for each row begin if new.duration 120 then set new.zt ...
oralce觸發器中更新本表的方法
oralce觸發器中更新本表的方法 sql create table create table test up tri id number,name varchar2 20 age number 2 中如何更新a表的其他字段。舉例說明 為該錶建立乙個觸發器,功能是 當name欄位發生改變時,將age...
觸發器的更新
如何用一條sql語句,同時更新兩個表中的資料 2009年01月03日 星期六 17 34 用觸發器 在a表建更新b表對應資料的觸發器 這樣a表更新了,相應b表資料也會更新 如有a表,欄位id int name varchar 50 b表,欄位id int namebak varchar 50 先建a...