【发布时间】:2018-10-20 23:09:15
【问题描述】:
我有这个程序,它计算为汽车支付的总金额,并确定如果金额等于价格,是否可以将汽车状态更改为“已售出”。
我知道问题出在 car_payment 中的查询,但我找不到其他方法来计算金额的总和,请有人帮助我吗?
create or replace trigger tr_paid_car
before insert
or update of amount
on car_payment
for each row
declare
v_amount number;
v_car_status_id car_status.car_status_id%type;
v_price car.price%type;
begin
select sum(amount)
into v_amount
from car_payment
where car_id = :new.car_id;
if inserting then
v_amount := v_amount + :new.amount;
elsif updating then
v_amount := v_amount + :new.amount - :old.amount;
end if;
select price
into v_price
from car
where car_id = :new.car_id;
if v_amount >= v_price then
select car_status_id
into v_car_status_id
from car_status
where description = 'SOLD';
update car
set car_status_id = v_car_status_id
where car_id = :new.car_id;
end if;
end;
/
【问题讨论】:
-
如果您必须在计算中使用触发器并触发正在查询的同一个表,那么最好的选择可能是 PRAGMA AUTONOMOUS_TRANSACTION 以避免变异表错误。
-
认真考虑不要使用触发器来执行应用程序逻辑。应用程序应调用 PL/SQL API 来报告汽车“已售出”。该 API 应检查付款金额是否等于价格,如果不相等,则向其调用者返回失败。
-
我支持@MatthewMcPeak 的评论。将此代码从触发器中取出。使用插入和更新过程构建一个包。将包上的执行权限授予您的开发人员和用户,但不允许直接在桌面上执行 DML。然后把这个逻辑放在程序中,你就很成功了。
标签: oracle plsql mutating-table