【发布时间】:2020-02-10 01:01:42
【问题描述】:
我找不到阻止人们在未来输入日期的语法。我有这个,但它不会工作?我只能使用 Oracle 的 SQL*Plus。
CONSTRAINT dateofenrolment CHECK (dateofenrolment <= sysdate)
【问题讨论】:
标签: sql oracle date sqlplus check-constraints
我找不到阻止人们在未来输入日期的语法。我有这个,但它不会工作?我只能使用 Oracle 的 SQL*Plus。
CONSTRAINT dateofenrolment CHECK (dateofenrolment <= sysdate)
【问题讨论】:
标签: sql oracle date sqlplus check-constraints
您不能在带有检查约束的 Oracle 中执行此操作。问题是检查约束中使用的函数必须是确定性的。也就是说,它们必须在给定相同参数的情况下返回相同的值。很明显,sysdate 不符合这个要求,因为它的值每次都在变化。
Oracle 施加此限制是因为check 约束不仅在数据插入(或修改)表中时为真,而且始终为真。
不过,您可以使用触发器做您想做的事。只需定义一个 insert 和 update 触发器即可防止错误值进入。
【讨论】:
如您所知,这不能直接:
SQL> create table test
2 (id number primary key,
3 datum date constraint ch_future check (datum <= sysdate)
4 );
datum date constraint ch_future check (datum <= sysdate)
*
ERROR at line 3:
ORA-02436: date or system variable wrongly specified in CHECK constraint
SQL>
幸运的是,有一个简单的解决方法:创建额外的 dummy 列,该列将 sysdate 作为默认值,然后在 check 约束中使用该列。不是内联(因为它无法完成):
SQL> create table test
2 (id number primary key,
3 dummy date default sysdate,
4 datum date constraint ch_future check (datum <= dummy)
5 );
)
*
ERROR at line 5:
ORA-02438: Column check constraint cannot reference other columns
但作为轮廓约束:
SQL> create table test
2 (id number primary key,
3 dummy date default sysdate,
4 datum date,
5 --
6 constraint ch_future check (datum <= dummy)
7 );
Table created.
SQL>
啊哈。表已创建。让我们测试一下。首先检查今天的日期:
SQL> select sysdate from dual;
SYSDATE
-------------------
03.06.2020 19:51:41
插入过去的日期值:
SQL> insert into test (id, datum) values (1, to_date('20.05.2020 13:30', 'dd.mm.yyyy hh24:mi'));
1 row created.
插入未来的日期值:
SQL> insert into test (id, datum) values (1, to_date('20.12.2020 23:30', 'dd.mm.yyyy hh24:mi'));
insert into test (id, datum) values (1, to_date('20.12.2020 23:30', 'dd.mm.yyyy hh24:mi'))
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_FUTURE) violated
SQL>
所以,是的 - 如果您可以忍受表格中的其他列,它会起作用。
【讨论】: