【发布时间】:2011-06-20 17:55:02
【问题描述】:
我开发了一个触发器来检查日期的有效性。它工作正常,因为它可以防止我存储无效日期,但我也收到一条奇怪的错误消息,我不知道为什么。我的代码如下:
CREATE OR REPLACE TRIGGER "CHECKDATEVALIDITY"
BEFORE INSERT OR UPDATE
ON Event
FOR EACH ROW
BEGIN
IF :NEW.day < 1 OR :NEW.month < 1 OR :NEW.month > 12
THEN
RAISE_APPLICATION_ERROR(-20101, 'Wrong date');
END IF;
IF :NEW.month = 4 OR :NEW.month = 6 OR :NEW.month = 9 OR :NEW.month = 11
THEN
IF :NEW.day > 30
THEN
RAISE_APPLICATION_ERROR(-20101, 'Wrong date');
END IF;
ELSIF :NEW.month = 2
THEN
IF (mod(:NEW.year, 4) = 0)
THEN
IF :NEW.day > 29
THEN
RAISE_APPLICATION_ERROR(-20101, 'Wrong date');
END IF;
ELSIF :NEW.day > 28
THEN
RAISE_APPLICATION_ERROR(-20101, 'Wrong date');
END IF;
ELSE
IF :NEW.day > 31
THEN
RAISE_APPLICATION_ERROR(-20101, 'Wrong date');
END IF;
END IF;
END checkDateValidity;
我得到的错误是:
错误 ORA-20101:错误日期 ORA-06512:在“USER587.CHECKDATEVALIDITY”第 28 行 ORA-04088:执行触发器“USER578.CHECKDATEVALIDITY”时出错。
我还注意到,我从调用的 RAISE_APPLICATION_ERROR 旁边的行中得到了错误。什么发出错误?
【问题讨论】:
-
您认为错误信息有什么“奇怪”之处?这对我来说似乎完全合适。
-
嗨@p.cambell 谢谢你的评论。我觉得奇怪的是触发器按预期工作,我认为语法没有问题,我已经彻底检查过,我找不到任何问题。我不知道从哪里看这一点。
-
为日期验证等常见功能发明我们自己的逻辑的问题在于我们弄错了规则。能被 100 整除的年份不是闰年,除非它们也能被 400 整除。也就是说,29-FEB-1900 是平年,29-FEB-2000 是闰年。你的逻辑允许 29-FEB-1900,它不应该。
-
这就是
RAISE_APPLICATION_ERROR所做的——它会引发错误。这就是触发器阻止更新成功的方式——通过引发错误,导致 Oracle 停止处理语句。请注意,错误堆栈中的第一个代码是 ORA-20101——数值直接来自您对RAISE_APPLICATION_ERROR的调用。代码完全按照您编写的方式执行。 -
您为什么不将日期存储为日期并让Oracle为您进行验证?如果您将日期存储在日期数据类型中,优化器还可以对日期执行智能操作。
标签: oracle triggers oracle10g ora-06512