どの

2017-05-14 3 views
0

にFKポイントで、私はその後、このどの

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

などのOracleでデータベースを持っているレコードのPKを更新するために、私は、要件に基づいて、私は学生のレコードを更新するために聞かせて宿題を持っており、私は '更新'を使用することはできません。

これらのコマンドは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 

私はこれをgoogleで行います。

SET CONSTRAINTS SYS_C007647 DEFERRED; 

ただし、このエラーが発生します。

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

私はいくつかの間違ったことをしていることは知っていますが、どうやってやるのかわからないのです。

ありがとうございました。

+0

あなたはCTEを使用して1つのステートメントでそれを更新することができます –

+0

@AluanHaddad宿題の要件は「follow updateを実行するために:studentNumを '200202'から '200204'に更新し、アップデート時には使用しないでください)。だから、CTEが要件を満たしているかどうかわかりません。 – fuxiuyin

答えて

0

別の表の別のレコードとのPK-FK関係が存在する場合、Oracleはレコードを更新できません。

  1. stu_choose_lesson、leave_applyメッセージテーブルのFK制約(studentテーブルのstudentNum列を指す)を無効にします。
  2. stu_choose_lesson、leave_apply、メッセージテーブルのレコードを更新します。
  3. 学生テーブルのレコードを更新します。
  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と今、あなたは両方のレコード(PKとFK)を更新することができますし、制約の再検証がCOMMITまでdeferrendなります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; 

それを定義します。

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

対処方法2 古い学生レコードを、制約を変更することはできません更新を実行しませんが、INSERT新しいSTUDENT、レコード、子テーブルを更新し、DELETE場合。私。 UPDATEを論理的に実行するには、をINSERT + DELETEを使用して実行します。

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

"レッスン"がプライマリキーの値を変更する場合、レッスンでは間違ったことを教えています。主キーの値を決して変更しないでください。新しいレコードを挿入し、古いレコードを削除する必要があります。主キーには3つの属性があります。

  1. これは決してNULLです。
  2. これはユニークです。
  3. ITは決して変更されません。

あなたが問題を抱えている理由は、ルール3に違反していることです。

Do not do this this!