说我有以下表格:
EMPLOYEE :
ID(PrimaryKey) | NAME | DESIGNATION
让我们说DESIGNATION可以有这些值:
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时才插入表格?
如果此人是管理员并向该虚拟列添加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)
)
/
没有任何方法可以在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'
。
如果员工的指定不是经理,您可以使用触发器来避免将数据插入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);
如果此解决方案有效,请告诉我。