結合を含んだ更新をする方法


はじめに

あるテーブルを更新するときに複数テーブルを連結して行いたい。
その方法を調べて実践したときにすこしはまったのでメモ。

UPDATE

まず通常の更新処理の記載方法をのせておきます。

UPDATE
 更新対象テーブル
SET
 更新項目 = 値
WHERE
 検索条件

INNER JOINの利用

結合をする方法としてINNER JOINがあります。
ORACLEの場合、UPDATE句にJOINは書けないためサブクエリ内で行う必要があります。

例えば下記の2つのテーブルがあるとします。

[TBL01]

CD NAME GROUP UPD_FLG
0001 田中 情報システム 1
0002 佐藤 インフラ 0
0003 斎藤 情報システム 1

[TBL02]

CD GROUP
0001 システム開発部
0002 インフラ
0003 システムソリューションズ

■今回やりたいこと
TBL01.CDと一致するTBL02.CDレコードのTBL02.GROUP値でTBL01.GROUPを更新します。
更新対象はTBL01.UPD_FLGが1のレコードです。

UPDATE
(
 SELECT
  T1.GROUP GROUP01,
 T1.UPD_FLG UPD_FLG01,
  T2.GROUP GROUP02
 FROM
  TBL01 T1
 INNER JOIN
  TBL02 T2
 ON
  T1.CD = T2.CD
)
SET
 GROUP01 = GROUP02
WHERE
 UPD_FLG01 = 1

実行結果は以下となります。
[TBL01]

CD NAME GROUP UPD_FLG
0001 田中 システム開発部 1
0002 佐藤 インフラ 0
0003 斎藤 システムソリューションズ 1

注意

上記のやり方では
更新するレコードが一意にならないとエラーが発生します。

ORA-01779:キー保存されていない表にマップする列は変更できません。

そのため、一意にならないとわかっているものに対してはこの処理が使えません。
(一意でもこのエラーが発生することがあるとも聞きますが…)

MERGE文の利用

上記の方法が使えないじゃん。となったので他の方法を調べるとMERGE文というものがありました。
MERGE文はINSERTとUPDATEを同時に行うことができます。
UPDATEだけも可能です。

MERGE INTO
 更新対象テーブル
USING
 更新対象データのソース
ON
 結合条件
WHEN MATCHED THEN UPDATE SET
 更新項目 = 値

上記のテーブルの例で記載します。

MERGE INTO
 TBL01 T1
USING 
(
 SELECT
  CD,
  GROUP
 FROM
  TBL02
)T2
ON
(
 T1.CD = T2.CD
)
WHEN MATCHED THEN UPDATE SET
 T1.GROUP = T2.GROUP

この場合でも先ほどのINNER JOINと同様の結果が得られます。

注意

上記のやり方では
ON句に更新項目を指定することはできません。
上記の例だと、T1.CDを更新したい。という場合にはON句の条件を考えなおす必要があります。

ORA-38104: ON句で参照する列は更新できません:XXXXXX

おわり

私の場合、INNER JOINの方法、MERGE文の方法どちらも利用することができず困ってしまったのですが
無理に結合をせずに、SELECT ~ FROM ~ WHERE EXISTS ~を使うことでほしい更新データを取得することができました。
その例はまた別途メモしようと思います。

参考書

SQLも様々な参考書がでています。

・イラストで理解 SQL はじめて入門

イラストで理解 SQL はじめて入門【電子書籍】[ 朝井淳 ]

価格:2,398円
(2020/11/25 14:11時点)


・スッキリわかるSQL入門 第2版 ドリル222問付き!

スッキリわかるSQL入門 第2版 ドリル222問付き!【電子書籍】[ 中山清喬 ]

価格:3,080円
(2020/11/25 14:13時点)


・SQL 第2版 ゼロからはじめるデータベース操作

SQL 第2版 ゼロからはじめるデータベース操作【電子書籍】[ ミック ]

価格:2,068円
(2020/11/25 14:17時点)


Amazonはこちら