請問觸發器與函數不能讀的錯誤訊息 |
尚未結案
|
zzmbeyond01
中階會員 ![]() ![]() ![]() 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
触发器/函数不能读的错误
错误吗如下:请问怎么解决啊!!
---------------------------
Error
---------------------------
ORA-04091: 表 STUDY.FD 发生了变化,触发器/函数不能读
ORA-06512: 在"STUDY.FD_INSERT_UPDATE_TRG", line 29
ORA-04088: 触发器 'STUDY.FD_INSERT_UPDATE_TRG' 执行过程中出错 View program sources of error stack?
---------------------------
是(Y) 否(N)
---------------------------
;触发器代码 CREATE OR REPLACE TRIGGER FD_Insert_Update_Trg BEFORE INSERT OR UPDATE ON FD For EACH ROW declare CURSOR C_ZL(p_zlh zlgk.zlh03%type) IS SELECT t.dm,t.dw,t.zlh01,t.zlh02,t.zlh03,t.zdb001,t.zdb002 FROM ZL t WHERE t.zlh03=p_zlh; V_ZL C_ZL%ROWTYPE; begin IF UPDATING THEN --如果坐落号或栋号发生变化 IF (:old.zlh03<>:new.zlh03) or (:old.dh02<>:new.dh02) THEN OPEN C_ZL(:new.zlh03); FETCH C_ZL INTO V_ZL; IF C_ZL%FOUND THEN UPDATE FD SET dm=V_ZL.dm,dw=V_ZL.dw,Zlh01=V_ZL.zlh01,Zlh02=V_ZL.zlh02,Zlh03=V_ZL.zlh03, Zdb001=V_ZL.zdb001,Zdb002=V_ZL.zdb002,dh01=:new.dh01,dh02=:new.dh02 WHERE zlh03=:old.zlh03 and dh02=:old.dh02; END IF; CLOSE C_ZL; END IF; end;發表人 - zzmbeyond01 於 2004/12/15 22:58:08 |
zzmbeyond01
中階會員 ![]() ![]() ![]() 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
找了份英文解决方法,但是还是不知道应该怎么写。,[(]
请大大指点 Hello,
This problem as you might be knowing occurs when you try to select the data from the same table on which the trigger is written. Also this problem is only with the row level trigger and not with the statement level trigger. However the limitation of the statement level trigger is it can not refer to :NEW or :OLD. So now the solution is to capture the value of :NEW or :OLD in the row level trigger (no select statement here) and store it in some global variable. And how do you get the global variable? Using package specification ! a variable declared in a package specification is global in nature. Then use the value so stored in the statement level trigger in the select statement. It will work. Other solution is to use pragma autonomous transaction. Try and let us know. All the best. Regards
|
Fishman
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
Hi zzmbeyond01, 你針對 Table FD 寫 Trigger,該 Trigger 中不能在 Select,Insert,Update 該 Table,否則就會產生該錯誤訊息!! 你是要 Update 同一筆資料嗎?如果是
可以用 :New.FieldName := NewValue; 或是 :New.FieldName := :Old.FieldName; 這種方式給值即可!
------
Fishman |
zzmbeyond01
中階會員 ![]() ![]() ![]() 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
请问Fishman大大:
(1)如果我不加where条件的话,该语句是不是更新的当前记录吧。如果要是一次变更很多条记录呢,会不会出问题?
:New.FieldName := NewValue;
(2)我想在该触发器trigger中级联更新另一个表,另一个表的数据为什么没有变化耶
IF (:old.zlh03<>:new.zlh03) or (:old.dh02<>:new.dh02) THEN OPEN C_ZL(:new.zlh03); FETCH C_ZL INTO V_ZL; IF C_ZL%FOUND THEN :new.dm:=V_ZL.dm; :new.dw:=V_ZL.dw; :new.zlh03:=V_ZL.zlh03; :new.dh01:=:new.dh02; --更新分户 当dh02或zlh03变化后,希望更新fh表,但是triger后发现fh并没有变化 update fh set dh02=:new.dh02,zlh03=:New.zlh03 where dh02=:old.dh02 and zlh03=:old.zlh03;發表人 - zzmbeyond01 於 2004/12/16 13:03:29 |
Fishman
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
Hi zzmbeyond01, 1. :new.FieldName := NewValue 代表更新目前此筆資料的 fieldName 欄為值為 NewValue,並不會有多筆資料的問題,因為你的 Trigger 是設定為 FOR Each Row,所以每一筆資料異動皆會被觸發 2.
也許 Corsor 是空的,所以沒也進入迴圈執行 update 動作
你得程式好像是在更新目前紀錄與 Table fh
update 指令忘了加 where Condition,會異動為最後一筆資料
------
Fishman |
zzmbeyond01
中階會員 ![]() ![]() ![]() 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
引言: Hi zzmbeyond01, 1. :new.FieldName := NewValue 代表更新目前此筆資料的 fieldName 欄為值為 NewValue,並不會有多筆資料的問題,因為你的 Trigger 是設定為 FOR Each Row,所以每一筆資料異動皆會被觸發 2. 也許 Corsor 是空的,所以沒也進入迴圈執行 update 動作 你得程式好像是在更新目前紀錄與 Table fh update 指令忘了加 where Condition,會異動為最後一筆資料 |
Fishman
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
Hi zzmbeyond01, Sorry !! 漏看了 where condition !! 有無可能是 :old.dh02 or :old.zlh03 是 Null 值? 若是此原因,
update fh set dh02=:new.dh02,zlh03=:New.zlh03 where dh02=:old.dh02 and zlh03=:old.zlh03;
不會有任何作用,因為在 Oracle 中 NULL <> NULL
------
Fishman |
zzmbeyond01
中階會員 ![]() ![]() ![]() 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
Fh是FD的从表,
我加了一句,并没有抱错,说明不是空 if :old.dh02=NULL or :old.zlh03=NULL then raise_application_error(-20000,'NULL'); end if; update fh set dh02=:new.dh02,zlh03=:New.zlh03 where dh02=:old.dh02 and zlh03=:old.zlh03;数据更改成功了,原来是fh表需要重新登陆数据库后就可以正确显示,怎么这么慢?? |
Fishman
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
Hi zzmbeyond01, 更正你一個觀念:
if :old.dh02=NULL or :old.zlh03=NULL then raise_application_error(-20000,'NULL'); end if;該程式是無用的,因為先前已提到,在 Oracle 中 NULL 不等於任何值,因此 raise_application_error 永遠沒有機會被觸發,你必須改成 if :old.dh02 is NULL or :old.zlh03 is NULL then raise_application_error(-20000,'NULL'); end if;方有作用!!
------
Fishman |
zzmbeyond01
中階會員 ![]() ![]() ![]() 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
|
zzmbeyond01
中階會員 ![]() ![]() ![]() 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
这样的触发器该如何写??折腾死人了
|
zzmbeyond01
中階會員 ![]() ![]() ![]() 發表:98 回覆:167 積分:53 註冊:2003-09-07 發送簡訊給我 |
ZL_UPDATE_TRG行级触发器更新ZL表时,先更新FD表,
触发FD_Insert_Update_Trg行级触发器去做更新FD表的动作,
FD_Insert_Update_Trg行级触发器在语句级触发器 FD_After_Update_Trg中使用了ZL表的select语句,而此时ZL表是(mutating table)变化表,oracle就抱错了,怎么解决??? 已经用了一个Oracle包,但是不行耶 發表人 - zzmbeyond01 於 2004/12/17 11:19:30
|
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |