##はじめに
あるテーブルを更新するときに複数テーブルを連結して行いたい。
その方法を調べて実践したときにすこしはまったのでメモ。
##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円 |
スッキリわかるSQL入門 第2版 ドリル222問付き!【電子書籍】[ 中山清喬 ] 価格:3,080円 |
SQL 第2版 ゼロからはじめるデータベース操作【電子書籍】[ ミック ] 価格:2,068円 |