仅接受所选值的外键

问题描述 投票:0回答:3

说我有以下表格:

EMPLOYEE : 
    ID(PrimaryKey) | NAME | DESIGNATION 

让我们说DESIGNATION可以有这些值:

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

    ID | NAME | SALARY

MANAGERS_DETAILS中的ID是EMPLOYEE表ID的外键.i.e,

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

反正是否限制插入不是经理人的员工?即只有当指定员工是MANAGER时才插入表格?

sql oracle database-design foreign-keys
3个回答
2
投票

如果此人是管理员并向该虚拟列添加EMPLOYEE约束,则可以向包含idUNIQUE表添加虚拟列。然后你可以引用它作为FOREIGN KEY

CREATE TABLE employee (
  id          NUMBER(10,0) PRIMARY KEY,
  name        VARCHAR2(100),
  designation VARCHAR2(10),
  idIfManager NUMBER(10,0) GENERATED ALWAYS AS (
                  CASE DESIGNATION WHEN 'MANAGER' THEN id END
                ) VIRTUAL
                CONSTRAINT employee__idIfManager__u UNIQUE
)
/

CREATE TABLE manager_details (
  id     NUMBER(10,0)
         PRIMARY KEY
         REFERENCES employee ( idIfManager ),
  name   VARCHAR2(100),
  salary NUMBER(12,2)
)
/

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);

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


0
投票

如果员工的指定不是经理,您可以使用触发器来避免将数据插入Manager表。您可能希望在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

© www.soinside.com 2019 - 2024. All rights reserved.