CHECK出生日期的约束? [英] CHECK constraint on date of birth?

查看:1103
本文介绍了CHECK出生日期的约束?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Oracle和emp_date中创建了我的雇员表,我想让它的出生日期不再回来过去,不能在将来设置?



这是否太复杂,无法在CREATE TABLE语句中实现?如果是这样,我想我必须跳过它,因为这是我必须创建约束的部分。

 ,emp_dob DATE NOT NULL 

CREATE TABLE employee(emp_id NUMBER(4)PRIMARY KEY
,emp_name VARCHAR2(40)NOT NULL
,emp_address VARCHAR2(60)NOT NULL
, emp_tel NUMBER(11)NOT NULL
,CONSTRAINT emp_tel_length CHECK(LENGTH(emp_tel)BETWEEN 9和11)
,emp_dob DATE NOT NULL
,CONSTRAINT check_date_of_birth CHECK(emp_dob BETWEEN DATE'1950-01 -01'AND sysdate))


解决方案

确定性。也就是说,特定行必须始终满足约束,或者它必须总是不能满足约束。但 SYSDATE 本质上是非确定性的,因为返回的值是不断变化的。因此,您不能定义调用 SYSDATE 或任何其他用户定义函数的 CHECK 约束。



如果您尝试在约束定义中引用 SYSDATE ,您会收到错误

  SQL> ed 
写文件afiedt.buf

1创建表t(
2 birth_date日期检查(日期'1900-01-01'和
之间的birth_date 3 sysdate)
4 *)
SQL> /
sysdate)
*
第3行的错误:
ORA-02436:在CHECK约束中错误指定的日期或系统变量


您可以创建一个 CHECK 约束,其中最小和最大日期都是硬编码,不太特别实用,因为你必须不断地删除并重新创建约束。

  SQL> ed 
写文件afiedt.buf

1创建表t(
2 birth_date日期检查(日期'1900-01-01'和
之间的birth_date 3 date' 2011-12-08')
4 *)
SQL> /

创建表。

实现这种要求的实际方法是在表上创建一个触发器

  CREATE OR REPLACE TRIGGER check_birth_date 
之前插入或更新员工
每个行
BEGIN
IF(:new.emp_dob< date'1900-01-01'或
:new.emp_dob> sysdate)
THEN
RAISE_APPLICATION_ERROR(
-20001,
'雇员出生日期必须晚于1900年1月1日,早于今天');
END IF;
END;


I am creating my employee table in Oracle and for emp_date I would like to make it so the date of birth is not way back in the past and can not be set in the future?

Is this too complex to implement in the CREATE TABLE statement? if so then I guess I have to skip it because that is the part where I have to create the constraints.

, emp_dob DATE NOT NULL

    CREATE TABLE employee(emp_id NUMBER(4) PRIMARY KEY
, emp_name VARCHAR2(40) NOT NULL
, emp_address VARCHAR2(60) NOT NULL
, emp_tel NUMBER(11) NOT NULL
, CONSTRAINT emp_tel_length CHECK (LENGTH(emp_tel) BETWEEN 9 and 11)
, emp_dob DATE NOT NULL
, CONSTRAINT check_date_of_birth CHECK (emp_dob BETWEEN DATE '1950-01-01' AND sysdate))

解决方案

Check constraints must be deterministic. That is, a particular row must always satisfy the constraint or it must always fail to satisfy the constraint. But SYSDATE is inherently non-deterministic since the returned value is constantly changing. Thus, you cannot define a CHECK constraint that calls SYSDATE or any other user-defined function.

If you try to reference SYSDATE in the constraint definition, you'll get an error

SQL> ed
Wrote file afiedt.buf

  1  create table t(
  2      birth_date date check( birth_date between date '1900-01-01' and
  3                                                sysdate )
  4* )
SQL> /
                                              sysdate )
                                              *
ERROR at line 3:
ORA-02436: date or system variable wrongly specified in CHECK constraint

You could create a CHECK constraint where both the minimum and maximum date were hard-coded but that would not be particularly practical since you'd have to constantly drop and recreate the constraint.

SQL> ed
Wrote file afiedt.buf

  1   create table t(
  2       birth_date date check( birth_date between date '1900-01-01' and
  3                                                 date '2011-12-08' )
  4*  )
SQL> /

Table created.

The practical way to enforce this sort of requirement would be to create a trigger on the table

CREATE OR REPLACE TRIGGER check_birth_date
  BEFORE INSERT OR UPDATE ON employee
  FOR EACH ROW
BEGIN
  IF( :new.emp_dob < date '1900-01-01' or 
      :new.emp_dob > sysdate )
  THEN
    RAISE_APPLICATION_ERROR( 
      -20001, 
      'EMployee date of birth must be later than Jan 1, 1900 and earlier than today' );
  END IF;
END;

这篇关于CHECK出生日期的约束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆