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
,您应该在 EMPLOYEES
和 STUDENTS
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_id
和 student_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
我的数据库中有 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
,您应该在 EMPLOYEES
和 STUDENTS
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_id
和 student_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