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

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

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

我们需要创建一个新表,其中包含每个学生的分支和类(class):

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

同样,我们不应该能够输入不属于学生当前就读的类(class)的分支,例如,如果我们有一个属于“计算机工程”类(class)的“软件工程”分支:

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

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

最佳答案

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

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

关于sql - 如何在sql中引用一对属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34338806/

相关文章:

mysql - Doctrine 异常的 1452 错误

php - 在 Laravel 中找不到错误列

sql - 为什么子查询和join这么慢

SQL 使用 IF 条件的列值

java - 无效的 SQL 类型 : sqlKind = UNINITIALIZED error is shown

oracle - Spring 事务不会在异常时回滚(Oracle JNDI 数据源)

java - 找不到适合 jdbc :oracle:thin:@localhost:1521:XE when running web application 的驱动程序

mysql - 时间戳当前时间非常适合记录用户注册,但是当我更新用户时它会改变吗?

mysql - 根据匹配记录从2个表中提取数据

ruby-on-rails - 连接表的 ListView