助け合いフォーラム

Oracle DB

Oracle Master Silver SQL 2019(1Z0-071)
問題ID : 26563
問題を開く
FOREIGN KEY制約の説明として正しいものはどれですか(該当するものを全て選択して下さい)。

正解

ON DELETE CASCADEオプションを指定すると、親表の行を削除する際に、親表を参照している子表の行も自動的に削除する

FOREIGN KEY制約を定義すると、依存する行の有無にかかわらず親表を削除できない

解説

FOREIGN KEY制約の親表に指定された表は、依存する行の有無にかかわらず削除することができません。
また、親表のデータを削除した場合の子表の振る舞いは、
・ON DELETE CASCADEオプション
・ON DELETE SET NULLオプション
を指定して設定できます。

ON DELETE CASCADEでは、親表の行が削除された場合、参照していた子表の行も同時に削除されます。
また、ON DELETE SET NULLでは、親表の行が削除された場合、参照していた子表の列にNULL値を設定します。

以上より、
・ON DELETE CASCADEオプションを指定すると、親表の行を削除する際に、親表を参照している子表の行も自動的に削除する
・FOREIGN KEY制約を定義すると、依存する行の有無にかかわらず親表を削除できない
が正解となります。

その他の選択肢については次のとおりです。

・ON DELETE CASCADEオプションを指定すると、親表の行を削除する際に、親表を参照している子表の行にNULL値を設定する
ON DELETE SET NULLの説明です。

・ON DELETE SET NULLオプションを指定すると、親表の行を削除する際に、親表を参照している子表の行も自動的に削除する
ON DELETE CASCADEの説明です。

・FOREIGN KEY制約を定義すると、依存する行がある場合のみ親表を削除できない
FOREIGN KEY制約の親表に指定された表は、依存する行の有無にかかわらず削除できません。

参考

列または列の組合せにFOREIGN KEY制約を定義すると、定義された列または列の組合せには参照先の列に存在する値しか登録できなくなります。ただしNULL値は登録することができ、複数の行にNULL値を登録する事もできます。

FOREIGN KEY制約は、次のように定義します。

 [列レベルで定義する場合]
 [CONSTRAINT 制約名] REFERENCES 親表名(参照する列[, 参照する列 …])

 [表レベルで定義する場合]
 [CONSTRAINT 制約名] FOREIGN KEY(列名[, 列名 …]) REFERENCES 親表名(参照する列[, 参照する列 …])


SQLを表示
CREATE TABLE parent
(
id NUMBER(2) CONSTRAINT id_pk PRIMARY KEY,
deptname VARCHAR2(10)
);

CREATE TABLE child
(
id NUMBER(2),
name VARCHAR2(10),
deptid NUMBER(2)
CONSTRAINT dept_fk REFERENCES parent(id)
);

INSERT INTO parent VALUES (1, 'Sales');

INSERT INTO child VALUES (1, 'Tanaka', 1);

INSERT INTO child VALUES (2, 'Sasaki', 2);




複数の列の組合せに対してFOREIGN KEY制約を定義する場合は、表レベルで定義します。


SQLを表示
CREATE TABLE parent
(
id NUMBER(2),
deptname VARCHAR2(10),
CONSTRAINT parent_pk PRIMARY KEY (id, deptname)
);

CREATE TABLE child
(
id NUMBER(2),
name VARCHAR2(10),
deptid NUMBER(2),
deptname VARCHAR2(10),
CONSTRAINT child_fk FOREIGN KEY (deptid, deptname)
REFERENCES parent (id, deptname)
);


FOREIGN KEY制約で参照できる親表の列は、PRIMARY KEY制約またはUNIQUE制約が定義されている列だけです。


SQLを表示
CREATE TABLE parent
(
id NUMBER(2),
deptname VARCHAR2(10)
);

CREATE TABLE child
(
id NUMBER(2),
name VARCHAR2(10),
deptid NUMBER(2)
CONSTRAINT dept_fk REFERENCES parent(id)
);


また、参照する親表に、FOREIGN KEY制約を定義する自表を指定することもできます。


SQLを表示
CREATE TABLE child
(
id NUMBER(2) CONSTRAINT child_pk PRIMARY KEY,
name VARCHAR2(10),
manager NUMBER(2)
CONSTRAINT mgr_fk REFERENCES child(id)
);


FOREIGN KEY制約の親表として指定された表は、参照されている行がない場合でも削除できなくなります。親表を削除したい場合は、FOREIGN KEY制約を定義した表を削除してから親表を削除します。


SQLを表示
CREATE TABLE parent
(
id NUMBER(2) CONSTRAINT pid_pk PRIMARY KEY,
name VARCHAR2(10)
);

CREATE TABLE child
(
id NUMBER(2),
name VARCHAR2(10),
deptid NUMBER(2)
CONSTRAINT dept_fk REFERENCES parent(id)
);

DROP TABLE parent;


FOREIGN KEY制約では、ON DELETE CASCADEオプションやON DELETE SET NULLオプションと組み合せて定義することもできます。これらのオプションを指定することで、親表のデータを削除した場合に、FOREIGN KEY制約を定義した子表のデータをどのようにするかを指定できます。




SQLを表示
CREATE TABLE parent
(
id NUMBER(2) CONSTRAINT pid_pk PRIMARY KEY,
dept_name VARCHAR2(10)
);

CREATE TABLE child
(
id NUMBER(2),
name VARCHAR2(10),
deptid NUMBER(2) CONSTRAINT dept_fk REFERENCES parent (id)
);  

INSERT INTO parent VALUES (1, 'SALES');

INSERT INTO child VALUES (1, 'Tanaka', 1);

DELETE FROM parent WHERE id = 1;



SQLを表示
CREATE TABLE parent
(
id NUMBER(2) CONSTRAINT pid_pk PRIMARY KEY,
dept_name VARCHAR2(10));

CREATE TABLE child
(
id NUMBER(2),
name VARCHAR2(10),
deptid NUMBER(2)
CONSTRAINT dept_fk REFERENCES parent (id) ON DELETE CASCADE
);

INSERT INTO parent VALUES (1, 'SALES');

INSERT INTO child VALUES (1, 'Tanaka', 1);

DELETE FROM parent WHERE id = 1;

SELECT * FROM child;



SQLを表示
CREATE TABLE parent
(
id NUMBER(2) CONSTRAINT pid_pk PRIMARY KEY,
dept_name VARCHAR2(10)
);

CREATE TABLE child
(
id NUMBER(2),
name VARCHAR2(10),
deptid NUMBER(2)
CONSTRAINT dept_fk REFERENCES parent (id)
ON DELETE SET NULL
);

INSERT INTO parent VALUES (1, 'SALES');

INSERT INTO child VALUES (1, 'Tanaka', 1);

DELETE FROM parent WHERE id = 1;

SELECT * FROM child;
上に戻る

親表の削除

投稿日 2025/07/10

選択肢3と4は、「親表の削除」とあるのでDROP TABLEのことかと思うのですが、「外部キー制約で参照されていなければエラーにならない」という認識でいたのですが違うのでしょうか。
chatGPTやGeminiに聞いてみても、3は間違いで4が正解という結果になり混乱しています。


A Ayame_0515

2025/07/10 14:21

3→ FOREIGN KEY制約を定義すると、依存する行の有無にかかわらず親表を削除できない 4→ FOREIGN KEY制約を定義すると、依存する行がある場合のみ親表を削除できない です。

2025/07/10 16:37

外部キー制約で参照されている列の値の更新や行の削除については、ご認識の通りだと思いますが、「表自体の削除」は依存する行の有無に関わらずできないようです。

SQL> CREATE TABLE tbl_parent (
  2  deptno NUMBER(4) PRIMARY KEY,
  3  name VARCHAR2(10)
  4  );

表が作成されました。

SQL> CREATE TABLE tbl_child(
  2  empno NUMBER(4) PRIMARY KEY,
  3  name VARCHAR2(10),
  4  deptno NUMBER REFERENCES tbl_parent(deptno)
  5  );

表が作成されました。

SQL> DROP TABLE tbl_parent;
DROP TABLE tbl_parent
           *
行1でエラーが発生しました。:
ORA-02449: 表の一意キーまたは主キーが外部キーに参照されています。


SQL> 

この問題の「参考」にも以下の記載があります。

FOREIGN KEY制約の親表として指定された表は、参照されている行がない場合でも削除できなくなります。親表を削除したい場合は、FOREIGN KEY制約を定義した表を削除してから親表を削除します。


コメント

A Ayame_0515

2025/07/10 16:55

ご回答ありがとうございます。 参照されていなければ表の削除はできる、と誤って覚えていたのでこの解説が疑問だったのですが、できないのですね…覚え直します!

この返信に対して
コメントを記入できます

この投稿に対して返信しませんか?