我将如何添加检查约束以确保日期不在未来

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 中插入(或修改)数据时为真,而且在所有时间都为真。

不过,您可以使用触发器来做您想做的事。只需定义一个 insertupdate 触发器以防止错误值进入。

如您所知,无法直接:

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 中的附加列,它就可以工作。