我的Oracle 10gr2检查约束有什么问题?试图强制执行日期范围
-
03-07-2019 - |
题
我想在日期范围内强制执行CHECK约束,以便BIRTH_DATE列中的所有日期都小于明天且大于或等于100年前。我在CHECK约束中尝试了这个表达式:
BIRTH_DATE >= (sysdate - numtoyminterval(100, 'YEAR')) AND BIRTH_DATE < sysdate + 1
但我收到错误“ORA-02436:在CHECK约束中错误指定的日期或系统变量”
有没有办法使用CHECK约束而不是触发器来完成此操作?
解决方案
检查约束表达式必须是确定性的,因此这种滑动日期范围在检查约束中是不可执行的。来自 SQL参考
检查条件的条件不能 包含以下构造:
* Subqueries and scalar subquery expressions * Calls to the functions that are not deterministic (CURRENT_DATE,
CURRENT_TIMESTAMP,DBTIMEZONE,LOCALTIMESTAMP,SESSIONTIMEZONE, SYSDATE,SYSTIMESTAMP,UID,USER和 USERENV)
其他提示
至于Oracle为什么会出现这种限制:检查约束必须始终评估为TRUE,即使对于更新也是如此。如果您将99岁的人添加到数据库中,然后在2年内尝试更新此人的电子邮件地址(例如),则会收到检查限制违规。
如果合适,您可以做的另一个列CREATED_DATE默认为SYSDATE,并制定约束:
BIRTH_DATE >= (CREATED_DATE - numtoyminterval(100, 'YEAR'))
AND BIRTH_DATE < CREATED_DATE + 1
但是,如果您真的只想在INSERT时执行检查,那么请在数据库触发器或API代码中执行此操作。
不隶属于 StackOverflow