質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.97%

ON DELETE、ON UPDATE をそれぞれCASCADEに設定した時の挙動

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 532
退会済みユーザー

退会済みユーザー

MySQLで親テーブルの更新/削除の時の挙動で、
ON DELETE
ON UPDATE をそれぞれCASCADEに設定しました。

親テーブルを削除すると、紐付いている子テーブルも更新削除されるようになったのですが、子テーブルをUPDATEをしようとするとエラーになってしまいました。

今、手元にエラー文が無いのですが、ON DELETE、ON UPDATE をCASCADEにしたことが原因のようです。
これを回避するにはどうすればいいのでしょうか?

親テーブル
id
name

子テーブル
id
parent_id(親テーブルid)  NULL有り
name

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

まずは

create table parent(pid int primary key,pname varchar(20));
create table child(cid int primary key,cname varchar(20),pid int,foreign key(pid) references parent(pid) on delete cascade on update cascade);
insert into parent values(1,'p1'),(2,'p2'),(3,'p3'),(4,'p4');
insert into child values(1,'c1-1',1),(2,'c1-2',1),(3,'c1-3',1),(4,'c2-1',2),(5,'c2-2',2),(6,'c3-1',3),(7,'c3-2',3);


その上で

delete from parent where pid=2;//childの4,5が削除
update parent set pid=5 where pid=3;//childの6,7のpidが5に変わる


ここまではOKですか?
ここで

update child set pid=4 where cid=6;//cid=6のpid=5を4に変える


parentにpid=4が存在するのでOK

update child set pid=6 where cid=7;//cid=7のpid=5を6に変える


parentに存在しないpidに変更しようとしても誓約にひっかかります

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/14 19:58

    ありがとうございました!
    よく確認したところ、親IDが存在しなくなっていたのが原因でした。

    キャンセル

+1

子テーブルをUPDATEをしようとするとエラーになってしまいました。

エラーになって当然です。子テーブルから連動して親テーブルまで書き換えるような機能はありません。

…というより、ON DELETE CASCADEはともかく、ON UPDATE CASCADEを恒常的に使わないといけない(関連付けられるキー自体の書き換えが相次ぐ)データベース設計自体に問題があると考えます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/13 20:05

    親テーブルはそのままで、子テーブル側のみの値を変えたかったのです。
    ON DELETE CASCADE、ON UPDATE CASCADEは親テーブルが変更された時だけ、子テーブルを更新するものではなかったんですね。
    ありがとうございます。

    キャンセル

  • 2019/03/13 20:07

    子テーブル側だけ値を変えたいにしても、(ON UPDATE CASCADEの前提となる)外部キーがかかっている以上は、親テーブルにあるものしか入れられません。

    キャンセル

0

現象を再現できるUPDATE、使っているテーブルのCREATE, データを何件かINSERT文、その時表示されたエラーメッセージを質問に追記しては?

たぶん、親テーブルに存在しないキーで子テーブルをUPDATEして、親テーブルにデータがない、って怒られたのでは?

親テーブルの更新/削除の時の挙動
>ON DELETE句やON UPDATE句にCASCADEを指定した場合は、親テーブルに対して更新を行うと子テーブルで同じ値を持つカラムの値も合わせて更新されます。また親テーブルに対して削除を行うと子テーブルで同じ値を持つデータが削除されます。

わからないからといって掲示板に質問する前に、使い方くらいググって調べたり、CASCADEを付つけない時の挙動を確認しては?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/13 19:57

    コメントありがとうございます。
    再現できるものができましたら修正させていたます。
    親テーブルの更新削除は特に問題ないです。親テーブルを更新削除すると、子テーブルも更新削除されます。
    今回問題なのは、子テーブル側を更新しようとした時の挙動です。

    キャンセル

  • 2019/03/13 21:22

    変更しようとした子テーブルのキーが親テーブルに存在しないのでエラーになったのでしょう。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.97%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる