如何在sql中引用一对属性?

时间:2015-12-17 15:53:39

标签: sql oracle foreign-keys

我们有几个表(在oracle sql中):

CREATE TABLE programs(
        prog_name VARCHAR2(50) PRIMARY KEY NOT NULL,
        prog_abbr VARCHAR2(50) NOT NULL

);
CREATE TABLE students (
        student_id NUMBER(10) PRIMARY KEY,
        student_program VARCHAR2(20) REFERENCES programs (prog_name)
);
CREATE TABLE branches (
        branch_name VARCHAR2(50) NOT NULL,
        prog_name VARCHAR2(50) NOT NULL REFERENCES programs(prog_name),         
        PRIMARY KEY(branch_name, prog_name)
);

表分支是程序的弱实体,因此我们有一个复合键。

我们需要创建一个包含每个学生的分支和程序的新表:

CREATE TABLE student_branches(
          student_id NUMBER(10) PRIMARY KEY REFERENCES students(student_id),
          branch_name VARCHAR2(50) NOT NULL,
          prog_name VARCHAR2(50) NOT NULL
);

问题1

我们如何制作,以便我们无法将student_id输入student_branches并且不属于他们自己的程序? 假设我们有一名学生:

INSERT INTO students VALUES ('1', 'Computer Engineering');

然后我们能够进入

INSERT INTO student_branches VALUES ('1','Some Branch' 'Electrical Engineering');

我想写一些类似的东西:

(student_id, prog_name) REFERENCES students (student_id, student_program)

要抓住那个约束,但是oracle并不接受它。

问题2

同样,我们也不应该进入不属于学生目前注册的课程的分支,例如,如果我们有分支机构,那么我们就不能进入该分支机构。"软件工程"属于该计划"计算机工程":

INSERT INTO branches VALUES ('1', 'Software', 'Computer Engineering');

我们不应该进入参加其他课程的学生阅读分支机构软件工程:

INSERT INTO student_branches VALUES ('1', 'Software', 'Computer Engineering');

我们解决了这个问题:

ALTER TABLE student_branches
    add foreign key(branch_name, prog_name) references branches(branch_name, prog_name);

但这是解决问题的正确方法吗?可以用类似的方式解决第一个问题吗?

1 个答案:

答案 0 :(得分:2)

你可以用同样的方式解决它;但是没有匹配的主键,因此您还需要在学生表上创建一个唯一键以供外键引用:

CREATE TABLE students (
  student_id      NUMBER(10)   CONSTRAINT students__si__pk PRIMARY KEY,
  student_program VARCHAR2(50) CONSTRAINT students__sp__fk REFERENCES programs (prog_name),
  CONSTRAINT students__si_sp__u UNIQUE ( student_id, student_program )
);

CREATE TABLE student_branches(
  student_id  NUMBER(10)   CONSTRAINT student_branches__si__pk PRIMARY KEY
                           CONSTRAINT student_branches__si__fk REFERENCES students(student_id),
  branch_name VARCHAR2(50) CONSTRAINT student_branches__bn__nn NOT NULL,
  prog_name   VARCHAR2(50) CONSTRAINT student_branches__pn__nn NOT NULL,
  CONSTRAINT student_branches__bn_pn__fk FOREIGN KEY ( branch_name, prog_name ) REFERENCES branches ( branch_name, prog_name ),
  CONSTRAINT student_branches__si_pn__fk FOREIGN KEY ( student_id, prog_name ) REFERENCES students ( student_id, student_program )
);