仅接受选定值的外键

时间:2018-09-05 08:47:47

标签: sql oracle database-design foreign-keys

说我有以下表格:

EMPLOYEE : 
    ID(PrimaryKey) | NAME | DESIGNATION 

让我们说“指定”可以具有以下值:

  1. 经理
  2. 工程师
  3. 等等等。
MANAGERS_DETAILS 

    ID | NAME | SALARY
MANAGERS_DETAILS中的

ID是EMPLOYEE表ID的外键,即

CONSTRAINT managers_details$fk1 FOREIGN KEY (ID) 
    REFERENCES EMPLOYEE(ID) ON DELETE CASCADE

是否仍然有限制插入不是MANAGERS的员工?即仅在指定员工为经理时才插入表格?

3 个答案:

答案 0 :(得分:2)

如果此人是经理,则可以将虚拟列添加到包含EMPLOYEE的{​​{1}}表中,并向该虚拟列添加id约束。然后,您可以将其引用为UNIQUE

FOREIGN KEY

答案 1 :(得分:1)

没有任何方法可以在Oracle中强制执行SQL ASSERTION。但是,您可以像这样捏造:

 alter table manager_details add designation varchar2(7) default 'MANAGER' not null;
 alter table manager_details add constraint md_mgr_ck check (designation = 'MANAGER');

现在向EMPLOYEE添加另一个约束:

alter table employee add constraint emp_uk unique (id, designation);

现在您可以将外键更改为:

CONSTRAINT managers_details$fk1 FOREIGN KEY (ID, designation) 
     REFERENCES EMPLOYEE(ID, designation);

这很复杂,但这确实意味着必须在EMPLOYEE中将MANAGER_DETAILS中的记录定义为'MANAGER'

答案 2 :(得分:0)

如果雇员的职务不是经理,则可以使用触发器来避免将数据插入到经理表中。 您可能要同时在Managers表中的记录的插入和更新上执行此触发器。

CREATE OR REPLACE TRIGGER manager_validation 
BEFORE INSERT OR UPDATE 
ON MANAGERS_DETAILS
FOR EACH ROW 
DECLARE
  desig VARCHAR2(10);
BEGIN

  SELECT designation
    INTO desig
    FROM employee
   WHERE id = :new.id;

  IF (desig != 'MANAGER') THEN 
    raise_application_error( -20001, 'Only Employees who are Managers can be inserted into table.');
  END IF; 

END;

下面是我的工作示例:

-- Create Employee Table
CREATE TABLE employee_ihm
  (
    id          NUMBER PRIMARY KEY,
    name        VARCHAR2(1),
    designation VARCHAR2(10)
  );

-- Create Managers table
CREATE TABLE managers
  (
    id     NUMBER REFERENCES employee_ihm(id) ON DELETE CASCADE,
    name   VARCHAR2(1),
    salary NUMBER
  );


-- Create trigger on insert and update on Managers table
CREATE OR REPLACE TRIGGER manager_validation BEFORE
  INSERT OR UPDATE
  ON managers 
  FOR EACH ROW 
  DECLARE
    desig VARCHAR2(10);
  BEGIN
    SELECT designation INTO desig FROM employee_ihm WHERE id = :new.id;
    IF (desig != 'MANAGER') THEN
      raise_application_error( -20001, 'Only Employees who are Managers can be inserted into table.');
    END IF;
  END;

INSERT INTO employee_ihm VALUES
  (1, 'A', 'MANAGER');
INSERT INTO employee_ihm VALUES
  (2, 'B', 'EMP');
INSERT INTO employee_ihm VALUES
  (3, 'C', 'MANAGER');
INSERT INTO employee_ihm VALUES
  (4, 'D', 'TEAMLEAD');
INSERT INTO employee_ihm VALUES
  (5, 'E', 'TEAMMEM');
INSERT INTO employee_ihm VALUES
  (6, 'F', 'MANAGER');

-- Employee id 1 will be inserted successfully
INSERT INTO managers VALUES
  (1, 'A', 200);

-- Employee id 2 will fail to get inserted into Managers
INSERT INTO managers VALUES
  (2, 'B', 300);

让我知道此解决方案是否有效。

Records in Managers Table

Error while inserting employee in Managers table who is not Manager