oracle 触发器问题

因为用户总是直接在数据库更改数据,我没办法维护几张表的数据正确性,所以我想写个触发器来解决,在用户更新结算表的信息时,计算结算金额更新到预算表中。下面是触发器代码:CRE... 因为用户总是直接在数据库更改数据,我没办法维护几张表的数据正确性,所以我想写个触发器来解决,在用户更新结算表的信息时,计算结算金额更新到预算表中。下面是触发器代码:
CREATE OR REPLACE TRIGGER budget_update
AFTER UPDATE OF ACTUALDATE,CLEARINGAMOUNT, CLEARINGSTATUS,PROJECTID,CONTRACTID ON tb_clearing --结算表
FOR EACH ROW

BEGIN
IF updating THEN
dbms_output.put_line('=====预算表更新开始=====');

--更新预算表信息

update tb_budget b --预算表
set b.actualoutlay = --实际支出字段
(select NVL(sum(c.clearingamount),0.0) --统计结算金额
from tb_clearing c --结算表
left join tb_contract con --合同表
on c.contractid = con.contractid
where con.isformal = '1' -- 正式合同
and con.contracttype = '0' --对内合同
and c.clearingstatus = '3' -- 审核通过
and to_char(c.actualdate, 'yyyy') = b.budgetyear --按照实际时间
and c.projectid = b.projectid);

update tb_budget set usablebudget=(Budgetamount-actualoutlay); --剩余预算,可用预算减去实际支出

dbms_output.put_line('=====预算表更新结束=====');

END IF;
END;
========================
现在我调试报错:

求帮助
展开
 我来答
Andy_Sun321
2014-08-08 · TA获得超过1376个赞
知道小有建树答主
回答量:811
采纳率:89%
帮助的人:727万
展开全部
提示已经讲得清楚: 表TEST.TB_CLEARING发生了变化, 触发器/函数不能读它.
在使用oracle行级(for earch row设定)触发器时要注意:
1.触发器不可以执行COMMIT、ROLLBACK或SAVEPOINT语句,而且不可以调用执行这些语句之一的函数或过程。
2.触发器不可以声明long或LONG RAW变量。
3.触发器不可以在定义它的表上执行DML操作(行级触发器)

你在该触发器中要读取触发器器所在的表的数据(数据DML操作), 这是不允许的.
你将行级触发改成表级触发, 即去掉for each fow试试. 反正在你的语句中也没有使用到NEW, OLD这两个行级触发器新值, 旧值记录.

另外, 粗看你的代码, 似乎更新没有针对性(没有针对内容有变更的记录对tb_budget进行更新), 这样做效率不高, 应该考虑优化你的更新逻辑和代码.
更多追问追答
追问
不行啊,去掉for each fow,没有执行里面的update 语句,直接跳过了
追答
有输出吗?
tzetzebaby0830
2014-08-08 · TA获得超过155个赞
知道小有建树答主
回答量:411
采纳率:100%
帮助的人:239万
展开全部
第一个update 后 commit试试
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式