【问题标题】:Oracle Inserting a row in a table only if a match found in some other tableOracle 仅当在其他表中找到匹配项时才在表中插入一行
【发布时间】:2015-03-27 07:50:03
【问题描述】:

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

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

现在,当在 Images 表中插入一行时,我应该检查employee_id / Student_id 是否存在于employees 表/student 表中,如果找到匹配项,则只需插入,否则不应该。

我想在 images 表上添加两个外键如下:

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

但是,如果我这样做。它不允许我插入空值。如何修改我的设计,以便每当我在图像表中插入一行时,它应该是一个雇员 ID 或一个学生 ID。

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

【问题讨论】:

  • 它不允许我插入空值 不,它肯定允许空值。看我的回答。
  • 您在为此触发之前是否厌倦了插入?

标签: oracle oracle11g insert foreign-keys constraints


【解决方案1】:

我想在 images 表上添加两个外键。

但是,如果我这样做。它不允许我插入空值。

当你说外键约束不允许 NULL 值时你错了。它肯定会允许 NULL 值。

测试用例

让我们在IMAGES 表上为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>

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

【讨论】:

    【解决方案2】:

    像你做的那样给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】:

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

      但是,您应该在EMPLOYEESSTUDENTS 表中定义一条“未知记录”,而不是插入NULL(可能带有id=-1,name='UNKNOWN'),然后插入- 1 到您的 IMAGES 表中。

      【讨论】:

        【解决方案4】:

        我建议您更改表 images 中的主键,并作为 PK 三列(image_id、employee_id 和 student_id)。

        编辑 1:基于评论

        我认为您以错误的方式计划了问题。如果图像同时适用于员工和学生,您应该有两个表,images_employees 和 images_students,分别具有外键 employee_id 和 student_id,当然还有图像的 id。 但是这样排有没有意义?

        id: 1 student_id: null image_name: 'something' 
        

        我不这么认为...请详细说明图像表的用途。

        【讨论】:

        • 如果这样做,我无法将空值添加到图像表中。但是,如果 student_id 有值,则employee_id 应该为空,反之亦然。另外,我需要检查要插入的employee_id/student_id 是否存在于employees/student 表中。如果找到匹配项,那么只有我应该插入。
        猜你喜欢
        • 2014-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-20
        • 2013-09-11
        • 1970-01-01
        • 2019-11-22
        相关资源
        最近更新 更多