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;
========================
现在我调试报错:
求帮助 展开
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;
========================
现在我调试报错:
求帮助 展开
2个回答
展开全部
提示已经讲得清楚: 表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进行更新), 这样做效率不高, 应该考虑优化你的更新逻辑和代码.
在使用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 语句,直接跳过了
追答
有输出吗?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询