我如何检查年份是否介于 2000 年和当前年份之间?

How do i CHECK if a year is between 2000 and the current year?

我需要为汽车创建一个table。

每辆汽车都有制造年份。制造年份必须在 2000 年和当前年份之间。

year_manufacture INTEGER CONSTRAINT nn_automobiles_year_manufacture NOT NULL 
                             CONSTRAINT ck_automobiles_year_manufacture 
                   CHECK ((year_manufacture>= 2000)AND(year_manufacture<= "current year")),

这是不可能的,根据 Restrictions on Check Constraints :

Conditions of check constraints cannot contain the following constructs:

[...]

  • Calls to the functions that are not deterministic (CURRENT_DATE, CURRENT_TIMESTAMP, DBTIMEZONE, LOCALTIMESTAMP, SESSIONTIMEZONE, SYSDATE, SYSTIMESTAMP, UID, USER, and USERENV)

您不能创建包含 SYSDATECHECK 约束,但可以使用 DML(Insert) 触发器来检查条件(考虑 year_manufacture 是日期类型 ) :

Create or Replace Trigger trg_chk_man_date
Before Insert On tab -- replace with your table's name
For Each Row
Begin
  if to_char(:new.year_manufacture,'YYYY') < 2000 
     or to_char(:new.year_manufacture,'YYYY') > to_char(sysdate,'YYYY') then
    Raise_Application_Error(-20001,'The Wrong Manufacture Year !');
  end if;
End;

如果 year_manufacture 是数字类型的列,那么只需考虑 :new.year_manufacture < 2000 and extract(year from sysdate) < :new.year_manufacture 正如@Wernfried Domscheit 已经指出的那样。

无法使用约束创建它。您可以使用虚拟列进行破解,但实际上您的要求没有多大意义。

今天无效的值将在五个月后有效。但是,约束必须在任何时候都有效(或无效)。

您所能做的就是创建一个触发器,在插入或更新时检查制造年份。会像这样:

CREATE OR REPLACE TRIGGER check_manufacture_date
   BEFORE UPDATE OR INSERT ON automobiles
   FOR EACH ROW
BEGIN
   IF :NEW.year_manufacture NOT BETWEEN 2000 AND EXTRACT(YEAR FROM SYSDATE) THEN
      raise_application_error(20001, 'Manufacture must be between 2000 and current year');
   END IF;
END;

看看这样的解决方法是否有帮助。

你已经被告知的一切都是正确的。由于您无法根据 SYSDATE 直接检查年份,因此请创建另一列 - THIS_YEAR - 它不会在您的代码中的任何地方使用。它会在每次插入时自动填充并获取当前年份。

约束(不能内联)然后将 YEAR_MANUFACTURETHIS_YEAR 进行比较。

SQL> create table cars
  2    (id               number         constraint pk_cars primary key,
  3     name             varchar2(20)   not null,
  4     this_year        number(4)      default extract (year from sysdate),
  5     year_manufacture number(4),
  6     --
  7     constraint ch_year_manufacture check (year_manufacture between 2000 and this_year)
  8    );

Table created.

SQL>

测试:

SQL> -- OK - after 2000, before 2019 (which is the current year)
SQL> insert into cars (id, name, year_manufacture) values (1, 'BMW', 2005);

1 row created.

SQL> -- Wrong - before 2000
SQL> insert into cars (id, name, year_manufacture) values (2, 'Mercedes', 1998);
insert into cars (id, name, year_manufacture) values (2, 'Mercedes', 1998)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_YEAR_MANUFACTURE) violated


SQL> -- Wrong - after 2019 (which is the current year)
SQL> insert into cars (id, name, year_manufacture) values (3, 'Cooper', 2020);
insert into cars (id, name, year_manufacture) values (3, 'Cooper', 2020)
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_YEAR_MANUFACTURE) violated


SQL> -- OK - current year
SQL> insert into cars (id, name, year_manufacture) values (4, 'Opel', 2019);

1 row created.

SQL>
SQL> select * from cars;

        ID NAME                  THIS_YEAR YEAR_MANUFACTURE
---------- -------------------- ---------- ----------------
         1 BMW                        2019             2005
         4 Opel                       2019             2019

SQL>