我将如何添加检查约束以确保日期不在未来
How would I add a check constraint for making sure a date is not in the future
我找不到阻止人们在未来输入日期的语法。我有这个但它不会工作?我只能使用 Oracle 的 SQL*Plus.
CONSTRAINT dateofenrolment CHECK (dateofenrolment <= sysdate)
您不能在 Oracle 中使用检查约束执行此操作。问题是检查约束中使用的函数必须是确定性的。也就是说,在给定相同参数的情况下,它们必须 return 相同的值。显然,sysdate
不满足这个要求,因为它的值每次都在变化。
Oracle 施加此限制是因为 check
约束不仅在 table 中插入(或修改)数据时为真,而且在所有时间都为真。
不过,您可以使用触发器来做您想做的事。只需定义一个 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>
啊哈。 Table 已创建。让我们测试一下。首先查看今天的日期:
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>
所以,是的 - 如果您可以接受 table 中的附加列,它就可以工作。
我找不到阻止人们在未来输入日期的语法。我有这个但它不会工作?我只能使用 Oracle 的 SQL*Plus.
CONSTRAINT dateofenrolment CHECK (dateofenrolment <= sysdate)
您不能在 Oracle 中使用检查约束执行此操作。问题是检查约束中使用的函数必须是确定性的。也就是说,在给定相同参数的情况下,它们必须 return 相同的值。显然,sysdate
不满足这个要求,因为它的值每次都在变化。
Oracle 施加此限制是因为 check
约束不仅在 table 中插入(或修改)数据时为真,而且在所有时间都为真。
不过,您可以使用触发器来做您想做的事。只需定义一个 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>
啊哈。 Table 已创建。让我们测试一下。首先查看今天的日期:
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>
所以,是的 - 如果您可以接受 table 中的附加列,它就可以工作。