【发布时间】:2014-12-06 09:19:57
【问题描述】:
我要做的是减少“车辆”表中每辆车的价值,以便当日期超过“上次更新”值一个月时,“价值”列减少 2.5%。触发器应在登录数据库后运行。问题是,一个 DBA 可能不会每天都登录数据库,所以如果距离上次登录已经过去了六个月,触发器将循环遍历,将值减少 2.5% 并执行 ADD_MONTHS(LastUpdate, 1)。
计算值的函数代码是:
REATE OR REPLACE FUNCTION fn_Vehicle_Value
(VehicleNumber IN NUMBER,
VehicleValue IN OUT NUMBER)
RETURN NUMERIC
IS
BEGIN
VehicleValue := VehicleValue - (VehicleValue * 0.025);
RETURN VehicleValue;
END;
/
这是我创建系统触发器的尝试:
CREATE OR REPLACE TRIGGER tg_VehicleDepreciate
AFTER LOGON ON DATABASE
IS
CURSOR vehicle_cur IS SELECT "VALUE", LastUpdate FROM Vehicle;
BEGIN
FOR vehicle_rec IN vehicle_cur LOOP
WHILE LastUpdate < SYSDATE LOOP
LastUpdate."Value" := fn_Vehicle_Update("VALUE");
UPDATE Vehicle
SET LastUpdate := ADD_MONTHS(LastUpdate, 1)
WHERE Vehicle# = vehicle_cur.Vehicle#;
END LOOP;
EXIT WHEN vehicle_cur%NOTFOUND;
END LOOP
END;
/
据我所知,我的功能是正确的。但是触发器没有编译并产生以下错误报告:
错误报告 - ORA-04079: 无效的触发器规范 04079. 00000 - “无效的触发规范” *原因:create TRIGGER 语句无效。 *操作:检查语句的语法是否正确。
我猜这是一个语法错误,但也可能是一个我无法解决的逻辑错误。
【问题讨论】:
-
为什么不创建一个“即时”计算的视图呢?我认为不需要为可以从现有数据派生的内容创建触发器(您需要在
vehicle表中添加“开始日期”或“创建日期”) -
这是一个单一的任务,我必须完全按照我被告知的去做。导师告诉我们需要使用函数和触发器。
-
通过
AFTER LOGON ON DATABASE触发器触发更新听起来有点愚蠢。例如,为什么不创建一个SCHEDULER JOB并在每个午夜运行一次? -
您的导师是否建议您使用“触发器”或
AFTER LOGON ON DATABASE触发器?
标签: sql oracle function plsql triggers