约会的约束

时间:2018-01-30 13:07:53

标签: oracle-sqldeveloper

我需要帮助在SQL Developer中实现数据库。我试图实现日期约束,但它不能按照我想要的方式工作。

这是Office表:

CREATE TABLE Office ( 
   Office_ID varchar2(7) PRIMARY KEY NOT NULL, 
   Office_AddressLine varchar2(50) NOT NULL, 
   Office_PostCode varchar2(8) NOT NULL, 
   Office_Telephone varchar2(11), 
   Office_Email varchar2(30), PRIMARY KEY(Office_ID), 
   CONSTRAINT Office_Email_CK CHECK ( Office_Email like '%_@__%._%')
);

这是Employee表:

CREATE TABLE Employee (
   Employee_ID varchar2(10) PRIMARY KEY NOT NULL,
   Office_ID varchar2(7) NOT NULL,
   Emp_FirstName varchar2(20) NOT NULL,
   Emp_LastName varchar2(20) NOT NULL,
   Emp_Gender varchar2(1) NOT NULL, 
   Emp_DateOfBirth Date NOT NULL,
   Hire_Date date NOT NULL,
   Emp_Telephone varchar2(11),
   Emp_Email varchar2(30),
   Emp_AddressLine varchar2(50) NOT NULL,
   Emp_PostCode varchar2(8) NOT NULL,
   Emp_Speciality varchar2(20) NOT NULL,
   Emp_Qualification varchar2(20) NOT NULL,
   Emp_AwardingBody varchar2(30) NOT NULL,
   Emp_Salary number(6) NOT NULL,
   Employment_History1 varchar2(50),
   Employment_History2 varchar2(50),
   Employment_History3 varchar2(50) ,
   CONSTRAINT fk_staff_office FOREIGN KEY (Office_ID) REFERENCES office (Office_ID),
   CONSTRAINT Emp_DateOfBirth_CK CHECK (Emp_DateOfBirth BETWEEN Date '1900-01-01' AND Date '2018-01-01'), 
   CONSTRAINT Emp_Gender_CK CHECK (Emp_Gender in ('M','F')), 
   CONSTRAINT Emp_Email_CK CHECK ( Emp_Email like '%_@__%._%')
);

它以这种方式工作,但我想要的是:

CREATE TABLE Employee (
   Employee_ID varchar2(10) NOT NULL,
   Office_ID varchar2(7) NOT NULL,
   Emp_FirstName varchar2(20) NOT NULL,
   Emp_LastName varchar2(20) NOT NULL,
   Emp_Gender varchar2(1) NOT NULL, Emp_DateOfBirth Date NOT NULL,
   Hire_Date date NOT NULL,
   Emp_Telephone varchar2(11),
   Emp_Email varchar2(30),
   Emp_AddressLine varchar2(50) NOT NULL,
   Emp_PostCode varchar2(8) NOT NULL,
   Emp_Speciality varchar2(20) NOT NULL,
   Emp_Qualification varchar2(20) NOT NULL,
   Emp_AwardingBody varchar2(30) NOT NULL,
   Emp_Salary number(6) NOT NULL,
   Employment_History1 varchar2(50),
   Employment_History2 varchar2(50),
   Employment_History3 varchar2(50) ,
   PRIMARY KEY (Employee_ID),
   CONSTRAINT fk_staff_office FOREIGN KEY (Office_ID) REFERENCES office (Office_ID) 
   CONSTRAINT fk_staff_patient FOREIGN KEY (Patient_ID) REFERENCES Patient (Patient_ID), 
   CONSTRAINT Emp_DateOfBirth_CK CHECK (Emp_DateOfBirth BETWEEN Date '1900-01-01' AND Date sysdate), 
   CONSTRAINT Hire_Date_CK CHECK (Hire_Date <= curdate()), 
   CONSTRAINT Emp_Gender_CK CHECK (Emp_Gender in ('M','F')), 
   CONSTRAINT Emp_Email_CK CHECK ( Emp_Email like '%_@__%._%')
);

我不知道为什么sysdate函数或getdate不起作用,我也不知道如何实现关于Hire_Date的约束(我无法用<=关系)。就像现在一样,即使我会失分,我也不得不放弃实施它们。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

您需要触发器来强制执行此类约束。这是一个例子:

SQL> create table test
  2  (
  3     employee_id   varchar2 (10),
  4     hire_date     date
  5  );

Table created.

SQL> create or replace trigger trg_hd_biu
  2     before insert or update of hire_date
  3     on test
  4     for each row
  5  begin
  6     if :new.hire_date not between date '1900-01-01' and sysdate
  7     then
  8        raise_application_error (-20001, 'Hire date out of range');
  9     end if;
 10  end;
 11  /

Trigger created.

SQL> insert into test values ('1', date '2018-01-15');

1 row created.

SQL> insert into test values ('2', date '2018-05-25');
insert into test values ('2', date '2018-05-25')
            *
ERROR at line 1:
ORA-20001: Hire date out of range
ORA-06512: at "SCOTT.TRG_HD_BIU", line 4
ORA-04088: error during execution of trigger 'SCOTT.TRG_HD_BIU'


SQL>

答案 1 :(得分:0)

我已经使用了另一种方法(因为我们的老师不希望我们创建触发器。我们必须只使用约束)并且它有效。非常感谢您的帮助。
CREATE TABLE Employee ( Employee_ID varchar2(10) PRIMARY KEY NOT NULL, Office_ID varchar2(7) NOT NULL, Emp_FirstName varchar2(20) NOT NULL, Emp_LastName varchar2(20) NOT NULL, Emp_Gender varchar2(1) NOT NULL, Emp_DateOfBirth Date NOT NULL, Hire_Date date NOT NULL, Emp_CurrentDate date default sysdate, Emp_Telephone varchar2(11) NOT NULL, Emp_Email varchar2(30) NOT NULL, Emp_AddressLine varchar2(50) NOT NULL, Emp_PostCode varchar2(8) NOT NULL, Emp_Speciality varchar2(20) NOT NULL, Emp_Qualification varchar2(20) NOT NULL, Emp_AwardingBody varchar2(30) NOT NULL, Emp_Salary number(6) NOT NULL, Emp_Supervised_By varchar2(10) NOT NULL, Employment_History1 varchar2(50), Employment_History2 varchar2(50), Employment_History3 varchar2(50) , CONSTRAINT fk_staff_office FOREIGN KEY (Office_ID) REFERENCES office (Office_ID), CONSTRAINT Hire_Date_CK check (Hire_Date < Emp_CurrentDate AND (Hire_Date - Emp_DateOfBirth)/365 > 18), CONSTRAINT Emp_DateOfBirth_CK check (Emp_DateOfBirth > TO_DATE('1900-01-01', 'YYYY-MM-DD')), CONSTRAINT Emp_Salary_CK check (Emp_Salary > 0 AND Emp_Salary < 150000), CONSTRAINT Emp_Gender_CK CHECK (Emp_Gender in ('M','F')), CONSTRAINT Emp_Email_CK CHECK ( Emp_Email like '%_@__%._%'), CONSTRAINT Emp_Telephone_CK CHECK (regexp_like(Emp_Telephone, '^[0123456789]{11}$') AND Emp_Telephone like '0%'), CONSTRAINT Emp_FirstName_CK CHECK (regexp_like(Emp_FirstName, '^[ABCDEFGHIJKLMNOPQRSTUVWXYZ]{1,20}$')), CONSTRAINT Emp_LastName_CK CHECK (regexp_like(Emp_LastName, '^[ABCDEFGHIJKLMNOPQRSTUVWXYZ]{1,20}$')), CONSTRAINT Emp_PostCode_CK CHECK (regexp_like ( Emp_PostCode , '([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))\s?[0-9][A-Za-z]{2})')), CONSTRAINT Emp_Speciality_CK CHECK (regexp_like(Emp_Speciality, '^[ABCDEFGHIJKLMNOPQRSTUVWXYZ ]{1,20}$')), CONSTRAINT Emp_Qualification_CK CHECK (regexp_like(Emp_Qualification, '^[ABCDEFGHIJKLMNOPQRSTUVWXYZ ]{1,20}$')), CONSTRAINT Emp_AwardingBody_CK CHECK (regexp_like(Emp_AwardingBody, '^[ABCDEFGHIJKLMNOPQRSTUVWXYZ ]{1,30}$')) );

我现在要做的是创建一个约束,使我能够在Emp_Speciality为&#39; Manager&#39;时自动将属性Emp_Supervised_By的值设置为Employee_ID属性的相同值。在此先感谢您的帮助!