2017-05-14 32 views
0

我有這樣如何更新記錄的PK與FK點

stu_choose_lesson ----> student <-----leave_apply 
          /|\ 
          | 
          | 
          |-------message 

在Oracle數據庫中。然後,我有一門功課這讓我更新學生的記錄,並根據要求我無法使用'更新'。

我在sqlplus中運行這些命令。

BEGIN 
UPDATE student SET studentNum=200204 WHERE studentNum=200202; 
UPDATE stu_choose_lesson SET studentNum=200204 WHERE studentNum=200202; 
UPDATE leave_apply SET studentNum=200204 WHERE studentNum=200202; 
UPDATE message SET studentNum=200204 WHERE studentNum=200202; 
END; 
/

然後我得到這個錯誤。

ORA-02292: integrity constraint (SYSTEM.SYS_C007646) violated - child record found 
ORA-06512: at line 1 

我谷歌它並做到這一點。

SET CONSTRAINTS SYS_C007647 DEFERRED; 

但我得到這個錯誤。

ORA-02447: cannot defer a constraint that is not deferrable 

我知道我做了一些錯誤的事情,但我不知道該怎麼做,以及如何谷歌它。

謝謝。

+0

您可以使用CTE並在一條語句中進行更新 –

+0

@AluanHaddad作業要求是「使用事務進行更新:將studentNum從'200202'更新爲'200204',並同時更新所有FK不要在更新中使用)「。所以,我不知道CTE是否達到要求。 – fuxiuyin

回答

0

當與另一個表中的另一條記錄存在PK-FK關係時,Oracle不會讓您更新記錄。您可以按照以下步驟操作:

  1. 在stu_choose_lesson,leave_apply消息表中禁用FK約束(指向學生表中的studentNum列)。
  2. 更新stu_choose_lesson,leave_apply,消息表中的記錄。
  3. 更新學生表中的記錄。 (請注意,sturent表必須是要更新的最後一個表,因爲它是主鍵)
  4. 在stu_choose_lesson,leave_apply消息表中啓用FK約束(第一步中禁用的約束)。

下面的腳本應該爲你工作,只需更換您的stu_choose_lesson與個位的約束名稱,leave_apply,消息表:

BEGIN 
alter table stu_choose_lesson 
DISABLE constraint 
<your FK_constraint name goes here>; 

alter table leave_apply 
DISABLE constraint 
<your FK_constraint name goes here>; 

alter table message 
DISABLE constraint 
<your FK_constraint name goes here>; 

UPDATE stu_choose_lesson SET studentNum=200204 WHERE studentNum=200202; 
UPDATE leave_apply SET studentNum=200204 WHERE studentNum=200202; 
UPDATE message SET studentNum=200204 WHERE studentNum=200202; 
UPDATE student SET studentNum=200204 WHERE studentNum=200202; 

alter table stu_choose_lesson 
ENABLE constraint 
<your FK_constraint name goes here>; 

alter table leave_apply 
ENABLE constraint 
<your FK_constraint name goes here>; 

alter table message 
ENABLE constraint 
<your FK_constraint name goes here>; 
END; 
/
0

所以這是描述你的問題一個小例子

設置

create table student (id number, name varchar2(100)); 
alter table student add primary key (id); 

create table student_lesson (id number, student_id number); 
alter table student_lesson add primary key (id); 
alter table student_lesson add constraint 
    fk_student_lesson FOREIGN KEY (student_id) 
    references student (id); 

-- data 
insert into student (id,name) values(1,'x'); 
insert into student_lesson (id,student_id) values(1,1); 
commit; 

問題

update student set id = 2 where id = 1; 
-- fails with ORA-02292 

的問題是,在沒有deferrable的第一個更新的約束無效FK約束。

解決方案1 ​​ 降contrain並定義DEFERRABLE

alter table student_lesson drop constraint fk_student_lesson; 
alter table student_lesson add constraint 
    fk_student_lesson FOREIGN KEY (student_id) 
    references student (id) 
    initially deferred deferrable; 

現在可以同時更新記錄(PK和FK)和約束的重新審定會deferrend直到COMMIT

update student set id = 2 where id = 1; 
update student_lesson set student_id = 2 where student_id = 1; 
commit 

溶液2 如果不能修改的約束,不進行更新,但INSERT學生記錄,更新子表和DELETE學生記錄。即使用INSERT + DELETE在邏輯上執行UPDATE

insert into student (id,name) values(2,'x'); 
update student_lesson set student_id = 2 where student_id = 1; 
delete from student where id = 1; 
commit; 
0

如果你的「課程」是改變主鍵的價值,你的教訓是教你做錯事。你永遠不應該改變一個主鍵的值 - 相反,應該插入一條新記錄,並且舊記錄應該被刪除。主鍵具有三個屬性:

  1. 它從不爲NULL。
  2. 它是獨一無二的。
  3. 它從未改變。

你遇到困難的原因是你違反規則#3。

不要這樣做!