我正在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 and 11)
, emp_dob DATE NOT NULL
, CONSTRAINT check_date_of_birth CHECK (emp_dob BETWEEN DATE '1950-01-01' AND sysdate))
答案 0 :(得分:9)
检查约束必须是确定性的。也就是说,特定行必须始终满足约束,否则它必须始终无法满足约束。但SYSDATE
本质上是非确定性的,因为返回的值不断变化。因此,您无法定义调用CHECK
或任何其他用户定义函数的SYSDATE
约束。
如果您尝试在约束定义中引用SYSDATE
,则会出现错误
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
您可以创建一个CHECK
约束,其中最小和最大日期都是硬编码的,但这不是特别实用,因为您必须不断删除并重新创建约束。
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.
强制执行此类要求的实际方法是在表格上创建触发器
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;
答案 1 :(得分:2)
另一种方法是创建一个域生日,并在域中内置约束。这将允许您在其他表定义中重用相同的类型。
CREATE DOMAIN birthdate AS date DEFAULT NULL
CHECK (value >= '1900-01-01' AND value <= now())
;
CREATE TABLE employee
( empno INTEGER NOT NULL PRIMARY KEY
, dob birthdate NOT NULL
...
);
答案 2 :(得分:1)
另一种解决方法
将sysdate写入列并将其用于验证。此列可能是您的审核列(例如:创建日期)
CREATE TABLE "AB_EMPLOYEE22"
(
"NAME" VARCHAR2 ( 20 BYTE ),
"AGE" NUMBER,
"SALARY" NUMBER,
"DOB" DATE,
"DOJ" DATE DEFAULT SYSDATE
);
Table Created
ALTER TABLE "AB_EMPLOYEE22" ADD CONSTRAINT
AGE_CHECK CHECK((ROUND((DOJ-DOB)/365)) = AGE) ENABLE;
Table Altered
答案 3 :(得分:0)
您需要使用DATE_OF_BIRTH和PRESENT_DATE创建一个表,即我使用了DATE_JOINING,然后通过减去DATE_JOINING减去DATE_OF_BIRTH来使用AGE默认值。
最后将CHECK约束设置为AGE是否大于您的要求,即我设置为20。
见下文
CREATE TABLE EMPLOYEE(
NAME VARCHAR(20) NOT NULL,
DOB DATE NOT NULL,
DATE_JOINING DATE DEFAULT NOW(),
AGE INTEGER DEFAULT TIMESTAMPDIFF(YEAR,DOB,DATE_JOINING) CHECK(AGE>20)
);
INSERT INTO EMPLOYEE(NAME,DOB) VALUES('NAYAK','1998-2-3');
Query OK, 1 row affected, 1 warning (0.128 sec)
SELECT * FROM EMPLOYEE;
+-------+------------+--------------+------+
| NAME | DOB | DATE_JOINING | AGE |
+-------+------------+--------------+------+
| NAYAK | 1998-02-03 | 2019-10-15 | 21 |
+-------+------------+--------------+------+
1 row in set (0.001 sec)
INSERT INTO EMPLOYEE(NAME,DOB) VALUES('NIRAJAN','2005-2-3');
ERROR 4025 (23000): CONSTRAINT `EMPLOYEE.AGE` failed for `NAYAK`.`EMPLOYEE`
答案 4 :(得分:0)
您可以直接使用间隔:
ALTER TABLE "students"
ADD CONSTRAINT "students_must_be_over_18" CHECK (
CURRENT_TIMESTAMP - "date_of_birth" > INTERVAL '18 years'
);