Oracle 仅当在其他 table 中找到匹配项时才在 table 中插入一行

Oracle Inserting a row in a table only if a match found in some other table

我的数据库中有 3 个 table,即员工、学生和图片

create table employees(id number primary key,name varchar2(100), address varchar2(100));
create table students(id number primary key,name varchar2(100),address varchar2(100));
create table Images (image_id number primary key,employee_id number,student_id number,image_name varchar2(100));

Insert into employees values (1,'asdfasd','asdfasdf');
Insert into employees values (2,'asdfasd','asdfasdf');
Insert into employees values (3,'asdfasd','asdfasdf');
Insert into employees values (4,'asdfasd','asdfasdf');
Insert into employees values (5,'asdfasd','asdfasdf');

Insert into students values (1,'asdfasd','asdfasdf');
Insert into students values (2,'asdfasd','asdfasdf');
Insert into students values (3,'asdfasd','asdfasdf');
Insert into students values (4,'asdfasd','asdfasdf');
Insert into students values (5,'asdfasd','asdfasdf');
Insert into students values (49,'asdfasd','asdfasdf');

Insert into Images(image_id,employee_id,image_name) values (1,5,'adsfasdfasdf');
Insert into Images(image_id,student_id,image_name) values (2,49,'asfasdfasdf');

现在,当在图像中插入一行时 table 我应该检查员工 table/student table 中是否存在 employee_id / Student_id ,如果找到匹配项,那么只有我必须插入否则它不应该。

我想在图像上添加两个外键 table 如下:

alter table images add constraint fk_employeeid foreign key(employee_id)
references employees(id);
alter table images add constraint fk_studentsid foreign key(student_id)
references students(id);

但是,如果我这样做了。它不允许我插入空值。我如何修改我的设计,以便每当我在图像 table 中插入一行时,它应该是 employee_id 或 student_id.

如果我造成任何混淆,这里是 link 代表 sql fiddle、http://www.sqlfiddle.com/#!4/92d24/1/0

我建议你在table张图片中更改主键,并有三列(image_id、employee_id和student_id)作为PK。

编辑 1:基于评论

我认为你以错误的方式计划了这个问题。如果图像同时用于员工和学生,则应该有两个 table,images_employees 和 images_students,分别带有外键 employee_id 和 student_id 和当然是图像的ID。 但是这样吵有什么意义吗?

id: 1 student_id: null image_name: 'something' 

我不这么认为...请详细解释图像的用途 table。

我会保留外键,这是正确的做法。

但不是插入 NULL,您应该在 EMPLOYEESSTUDENTS table 中定义一个 "unknown record"(也许有一个 id =-1, name='UNKNOWN'), 然后将 -1 插入 IMAGES table.

I thought of adding two foreign keys on the images table.

But, If I do so. It will not allow me to insert null values.

你说外键约束不允许 NULL 值是错误的。它肯定会允许 NULL 值。

测试用例

让我们在 IMAGES table 上为 employee_idstudent_id 添加 外键约束

ALTER TABLE images ADD CONSTRAINT fk_emp FOREIGN KEY(employee_id) REFERENCES employees(ID);
ALTER TABLE images ADD CONSTRAINT fk_stu FOREIGN KEY(student_id) REFERENCES students(ID);

让我们用 NULL 值检查 INSERT

SQL> INSERT INTO Images(image_id,employee_id,image_name) VALUES (1,5,'adsfasdfasdf');

1 row created.

SQL> INSERT INTO Images(image_id,student_id,image_name) VALUES (2,49,'asfasdfasdf');

1 row created.

SQL> INSERT INTO Images(image_id,employee_id,image_name) VALUES (3,null,'adsfasdfasdf');

1 row created.

SQL> INSERT INTO Images(image_id,student_id,image_name) VALUES (4,null,'asfasdfasdf');

1 row created.

SQL>
SQL> COMMIT;

Commit complete.

SQL>
SQL> SELECT * FROM images;

  IMAGE_ID EMPLOYEE_ID STUDENT_ID IMAGE_NAME
---------- ----------- ---------- ---------------
         1           5            adsfasdfasdf
         2                     49 asfasdfasdf
         3                        adsfasdfasdf
         4                        asfasdfasdf

SQL>

让我们检查一下外键约束验证:

SQL> INSERT INTO Images(image_id,employee_id,image_name) VALUES (1,10,'adsfasdfasdf');
INSERT INTO Images(image_id,employee_id,image_name) VALUES (1,10,'adsfasdfasdf')
*
ERROR at line 1:
ORA-00001: unique constraint (LALIT.SYS_C0010739) violated


SQL> INSERT INTO Images(image_id,student_id,image_name) VALUES (2,20,'asfasdfasdf');
INSERT INTO Images(image_id,student_id,image_name) VALUES (2,20,'asfasdfasdf')
*
ERROR at line 1:
ORA-00001: unique constraint (LALIT.SYS_C0010739) violated


SQL>

所以,一切都按照设计进行。

像您一样向 images 添加约束。再添加一个约束条件:

alter table images add constraint chk_nulls 
  check (
    (employee_id is not null and student_id is null)
    or (employee_id is null and student_id is not null) 
    );

这样您就不能同时为 employee_id 和 student_id 插入空值或非空值。并且还检查了外键。

测试:

insert into images values (1, 1, null, 'not important');      -- OK
insert into images values (2, null, null, 'not important');   -- error
insert into images values (3, 1, 1, 'not important');         -- error
insert into images values (4, null, 1, 'not important');      -- OK