我有两张表:student
和faculty
我在student
表中添加了一列,该列是引用faculty
中列的外键。
让我们说教师的身份 更改 。根据下面的代码,我的student
表会相应更新吗?或者我是否需要做额外的事情以确保更新?例如,假装James的id从1更新为99. student
的advisorid列会相应更新吗?
注意 - 我正在使用LINQPad而我无法对此进行测试,因为当我尝试对引用的表进行更改时,我得到Error 547: The UPDATE statement conflicted with the REFERENCE constraint "FK__enroll__studenti__178D7CA5". The conflict occurred in database "tempdb", table "dbo.enroll", column 'studentid'
。
alter table student
add advisorid int foreign key(advisorid) references faculty(facultyid);
update student set advisorid = 1 where studentid = 1;
select * from student
select * from faculty;
答案 0 :(得分:1)
正如您所见,默认情况下,外键所基于的键的更新不会传播到依赖列。您可以通过指定on update
子句来获得此类行为:
alter table student
add advisorid int foreign key(advisorid) references faculty(facultyid)
on update cascade;
修改强>
要回答注释中的问题,还可以在删除行时定义行为:
alter table student
add advisorid int foreign key(advisorid) references faculty(facultyid)
on delete cascade
on update cascade;
答案 1 :(得分:0)
在Oracle中ON UPDATE CASCADE
不起作用。在这里,我将演示另一种更新方案。
不是指定ON UPDATE CASCADE,而是可以将约束的检查推迟到事务结束。因此约束必须是DEFERRABLE。遗憾的是,无法修改约束,因此必须删除并重新创建约束。
这是一个例子:
CREATE TABLE parent_ (
pid NUMBER CONSTRAINT pk_parent PRIMARY KEY,
c1 VARCHAR2(50)
);
CREATE TABLE child_ (
cid NUMBER,
pid NUMBER CONSTRAINT fk_child_parent REFERENCES parent_(pid) ON DELETE CASCADE, --DEFERRABLE,
c1 VARCHAR2(50)
);
INSERT INTO parent_ VALUES (1, 'two');
INSERT INTO child_ VALUES (2, 1, 'two');
COMMIT;
更新主键或外键将导致oracle异常
UPDATE parent_ SET pid = 2
Fehlerbericht -
SQL-Fehler: ORA-02292: integrity constraint (ME.FK_CHILD_PARENT) violated - child record found
02292. 00000 - "integrity constraint (%s.%s) violated - child record found"
*Cause: attempted to delete a parent key value that had a foreign
dependency.
*Action: delete dependencies first then parent or disable constraint.
UPDATE child_ SET pid = 2
Fehlerbericht -
SQL-Fehler: ORA-02291: integrity constraint (ME.FK_CHILD_PARENT) violated - parent key not found
02291. 00000 - "integrity constraint (%s.%s) violated - parent key not found"
*Cause: A foreign key value has no matching primary key value.
*Action: Delete the foreign key or add a matching primary key.
现在外键将被重新创建为可延迟。它仍然会导致外键约束违规,但可以设置为每个会话延迟。优点是所有其他会话仍然像以前一样。
ALTER TABLE child_ DROP CONSTRAINT fk_child_parent;
ALTER TABLE child_ ADD CONSTRAINT fk_child_parent FOREIGN KEY (pid) REFERENCES parent_(pid) ON DELETE CASCADE DEFERRABLE;
ALTER SESSION SET CONSTRAINTS = DEFERRED;
UPDATE parent_ SET pid = 2;
UPDATE child_ SET pid = 2;
COMMIT;
ALTER SESSION SET CONSTRAINTS = IMMEDIATE;
创建外键(也是内联)时也可以设置DEFERRABLE属性。在official documentation
中详细了解相关信息