Внешний ключ, который принимает только выбранные значения - PullRequest
0 голосов
/ 05 сентября 2018

Скажите, у меня есть следующие таблицы:

EMPLOYEE : 
    ID(PrimaryKey) | NAME | DESIGNATION 

Допустим, DESIGNATION может иметь следующие значения:

  1. МЕНЕДЖЕР
  2. ENGINEER
  3. и т. Д. И т. Д.
MANAGERS_DETAILS 

    ID | NAME | SALARY

ID в MANAGERS_DETAILS - это внешний ключ таблицы EMPLOYEE ID.i.e,

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

Можно ли как-то ограничить включение сотрудников, которые не являются МЕНЕДЖЕРАМИ? т.е. вставлять в таблицу только тогда, когда обозначение сотрудника МЕНЕДЖЕР?

Ответы [ 3 ]

0 голосов
/ 05 сентября 2018

Вы можете добавить виртуальный столбец в таблицу EMPLOYEE, которая содержит id, если человек является менеджером, и добавить ограничение UNIQUE для этого виртуального столбца. Тогда вы можете сослаться на это как 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)
)
/
0 голосов
/ 05 сентября 2018

Вы можете использовать триггер, чтобы избежать вставки данных в таблицу «Менеджер», если сотрудник не является менеджером. Возможно, вы захотите выполнить этот триггер как при вставке, так и при обновлении записей в таблице менеджеров.

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

0 голосов
/ 05 сентября 2018

Нет никакого способа применить SQL ASSERTION в Oracle. Тем не менее, вы могли бы выдумать, как это:

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

Теперь добавьте еще одно ограничение для РАБОТНИКА:

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

Теперь вы можете изменить внешний ключ на:

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

Это сложно, но это означает, что записи в MANAGER_DETAILS должны быть определены как 'MANAGER' в EMPLOYEE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...