【发布时间】:2016-10-29 09:55:17
【问题描述】:
我正在尝试验证 Oracle 表中的范围值。表名YEAR_RANG是这样的
ID YEAR_FROM YEAR_TO
1 1950 1980
2 2001 2009
3 2010 2015
4 2016 2020
这里我想做一个约束,两行的年份范围不能重叠。我正在尝试使用以下触发器来做到这一点,
CREATE OR REPLACE TRIGGER YEAR_RANG_VALID
BEFORE INSERT or UPDATE on YEAR_RANG
FOR EACH ROW
DECLARE
o_exst NUMBER;
BEGIN
select count(*) into o_exst
FROM YEAR_RANG
WHERE
id != :new.id
and GREATEST(YEAR_FROM,:new.YEAR_FROM) <= LEAST(YEAR_TO,:new.YEAR_TO)
and ROWNUM = 1;
IF o_exst = 1 THEN
raise_application_error( -20202, 'Range overlap');
END IF;
END;
这适用于输入,但对于更新,它给出了这个错误
[42000][4091] ORA-04091: table DB.YEAR_RANG is mutating, trigger/function may not see it
ORA-06512: at "DB.YEAR_RANG_VALID", line 4
ORA-04088: error during execution of trigger 'DB.YEAR_RANG_VALID'
更改为“在 YEAR_RANG 上插入或更新之后”也无济于事。如何进行验证检查?我的触发器没问题还是有更好的方法?
还有一件事,我无法在应用程序级别检查这一点,因为这是从通用 CRUD 框架调用的,DB fail 是检测约束失败的唯一方法。
【问题讨论】:
-
你不能创建一个触发器来获取你正在插入的同一个表中的值,至少不是 BEFORE 类型的。看看您是否可以通过 AFTER insert 或 update 获得它。不记得是否可能。
-
@TigerCoder 你试过语句级触发器吗? stackoverflow.com/questions/10167346/…
-
由于该表显然只有少量行,@vercelli 对语句级触发器的建议非常合适:只需检查语句 no 重叠之后表中存在行。 (如果表格有数百万行,那么您就不想这样做了。)
-
@vercelli 语句级触发器就是答案。谢谢(你的)信息。如果您能给出您的评论作为答案,我会接受。
标签: database oracle validation oracle11g triggers