我正在尝试添加检查约束以检查年龄和出生日期

时间:2014-03-20 05:31:30

标签: sql oracle

CREATE TABLE "TEST"."AB_EMPLOYEE22" 
   (    "NAME" VARCHAR2(20 BYTE), 
    "AGE" NUMBER, 
    "SALARY" NUMBER, 
    "DOB" DATE
   ) 

alter table "TEST"."AB_EMPLOYEE22" add constraint
Age_check check((ROUND((sysdate-DOB)/365)) = AGE) ENABLE  

但是这个查询不起作用。 请帮帮我

5 个答案:

答案 0 :(得分:3)

免责声明:这不是问题的直接答案。

现在,不要在表格中存储派生的,最重要的是不断变化的数据,例如age。而是在查询时(例如使用视图)动态计算它。

CREATE TABLE ab_employee22
(
  name VARCHAR2(20), 
  salary NUMBER, 
  dob DATE
); 

CREATE VIEW ab_employee22_view AS
SELECT name, salary, dob,
       FLOOR(MONTHS_BETWEEN(sysdate, dob) / 12) age
  FROM ab_employee22;

这是 SQLFIddle 演示

答案 1 :(得分:1)

您不能在检查约束中使用SYSDATE。根据Oracle文档 - Check Constraint

  

检查条件的条件不能   包含以下构造:

     
      
  • 子查询和标量子查询表达式
  •   
  • 调用不确定的函数(CURRENT_DATE,
      CURRENT_TIMESTAMP,DBTIMEZONE,
      LOCALTIMESTAMP,SESSIONTIMEZONE,
       SYSDATE ,SYSTIMESTAMP,UID,USER和   USERENV)
  •   
  • 调用用户定义的函数
  •   
  • 取消引用REF列(例如,使用DEREF函数)
  •   
  • 嵌套表格列或属性
  •   
  • 伪列CURRVAL,NEXTVAL,LEVEL或ROWNUM
  •   
  • 未完全指定的日期常量
  •   

因此,在这种情况下,您可以使用Trigger来获得所需的输出。在这里,触发器将根据您的要求正常工作:

CREATE OR REPLACE TRIGGER trg_check_date
BEFORE INSERT OR UPDATE ON AB_EMPLOYEE22
FOR EACH ROW
BEGIN

  IF(ROUND((sysdate-nvl(:NEW.DOB,:OLD.DOB))/365) <> nvl(:NEW.AGE,:OLD.AGE))
  THEN
    RAISE_APPLICATION_ERROR( -20001, 'Your Date of Birth and Age do not match');
  END IF;

END;

如果您发现此触发器有任何困难,请随时写下评论。

答案 2 :(得分:0)

无法在约束中使用“Sysdate”等系统变量。 链接:http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:465820332843

建议使用具有相同逻辑的触发器

答案 3 :(得分:0)

忘记了SYSDATE,因为它无效或使用触发器来解决方法。我会告诉你一个便宜的技巧!!!

将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

答案 4 :(得分:-1)

您错过了圆函数的参数。

   alter table AB_EMPLOYEE22 add constraint
Age_check check((ROUND((sysdate-DOB)/365,0)) = AGE) ENABLE