SQL初心者が頑張って勉強中です。
今回はmerge文とdual表を使ってUPSERTする方法をアウトプットしたいと思います。
#UPSERTとは、
UPSERTはINSERTとUPSERTを合体して、一つの文にしたような処理を指すもので、UPSERTという構文はない。
該当する行がない時はINSERTして、ある時はUPDATEしたいときの処理をUPSERTということがある。
#merge文でUPSERT
merge文を使えばUPSERTができる。
例えば、ユーザーワークテーブルにあるデータとユーザーマスタにあるデータをmergeするときはこんな感じ。
ワークテーブルのユーザーIDがユーザーマスタにあったら、UPDARTして、なかったらINSERTしてくれる。
MERGE INTO ユーザーマスタ T1 --登録先のデータ
USING (
--登録元のデータ
SELECT
S1.ユーザーID
,S1.氏名
,S1.パスワード
FROM
一時ユーザーテーブル S1
)
ON (
--登録先のデータと登録元のデータを結合
--(登録元のデータが登録先に登録されているかどうかの判定)
T1.ユーザーID = S1.ユーザーID
)
WHEN MATCHED THEN
--登録先すでに存在している場合
UPDATE SET
T1.氏名 = S1.氏名
,T1.パスワード = S1.パスワード
WHEN NOT MATCHED THEN
--登録先に存在しない場合
INSERT
(ユーザーID, 氏名, パスワード)
VALUES
(S1.ユーザーID, S1.氏名, S1.パスワード)
では、mergeしたいデータはテーブル上にない場合はどうするのか?
(例えば、画面からEXCELファイルをアップロードして、ファイルに書いてある内容をUPSERTしたいとき)
#DUAL表を使う
dual表とは、、、
DUAL 表とは、オラクル固有のディクショナリ表の 1つで、DUMMY カラムだけで作成されている。
DUMMY カラムには 'X' という 1 レコードだけが存在する。
DUAL 表のオーナは SYS であるが、 PUBLIC シノニム宣言によって すべてのユーザーから DUAL としてアクセスが可能になっている。
DUAL 表は通常の1 レコードの表とは異なりオプティマイザによって、特別な 実行計画 (FAST_DUAL) が生成される。
一般的な使い方としては、SQL での関数の呼び出しや確認に使用される
(SHIFT the Oracleより抜粋)
どうやら、ダミーカラムしかなくて、具体的なデータを持たせるテーブルとは全く異なり、関数を使ったり、動作確認をするため
偽物テーブルみたいな便利な存在らしい、、、。
画面上から受け取ったデータは、このdual表を使ってUPSERTすることができる。
こんな感じ、、、
MERGE INTO ユーザーマスタ A
USING (SELECT ? ユーザーID, ? 氏名, ? パスワード FROM DUAL) B
ON ( A.ユーザーID=B.ユーザーID )
WHEN MATCHED THEN
UPDATE SET
A.氏名 = B.氏名
,A.パスワード = B.パスワード
WHEN NOT MATCHED THEN
INSERT
(ユーザーID, 氏名, パスワード)
VALUES
(B.ユーザーID, B.氏名, B.パスワード)
例えば画面から受け取った情報をlistに入れて、prepareStatementとdual表を使えばいい感じにUPSERTできるはず、、、!
#参考文献
https://lightgauge.net/database/sqlserver/2446/
https://omachizura.com/2016/06/sql-merge.html
https://www.drk7.jp/MT/archives/lite/001386.html