データ変更CTEを使用する :
WITH ins1 AS (
INSERT INTO sample(firstname, lastname)
VALUES ('fai55', 'shaggk')
-- ON CONFLICT DO NOTHING -- optional addition in Postgres 9.5+
RETURNING id AS sample_id
)
, ins2 AS (
INSERT INTO sample1 (sample_id, adddetails)
SELECT sample_id, 'ss' FROM ins1
RETURNING user_id
)
INSERT INTO sample2 (user_id, value)
SELECT user_id, 'ss2' FROM ins2;
各INSERT 前のものに依存します。 SELECT VALUESの代わりに 前のINSERTから行が返されない場合は、補助テーブルに何も挿入されないようにします 。 (Postgres 9.5以降では、ON CONFLICTを追加できます。 。)
この方法では、少し短くて高速です。
通常、完全なデータ行を1か所に提供する方が便利です。 :
WITH data(firstname, lastname, adddetails, value) AS (
VALUES -- provide data here
('fai55', 'shaggk', 'ss', 'ss2') -- see below
, ('fai56', 'XXaggk', 'xx', 'xx2') -- works for multiple input rows
-- more?
)
, ins1 AS (
INSERT INTO sample (firstname, lastname)
SELECT firstname, lastname -- DISTINCT? see below
FROM data
-- ON CONFLICT DO NOTHING -- UNIQUE constraint? see below
RETURNING firstname, lastname, id AS sample_id
)
, ins2 AS (
INSERT INTO sample1 (sample_id, adddetails)
SELECT ins1.sample_id, d.adddetails
FROM data d
JOIN ins1 USING (firstname, lastname)
RETURNING sample_id, user_id
)
INSERT INTO sample2 (user_id, value)
SELECT ins2.user_id, d.value
FROM data d
JOIN ins1 USING (firstname, lastname)
JOIN ins2 USING (sample_id);
db<>ここでフィドル
スタンドアロンのVALUESで明示的な型キャストが必要になる場合があります 式-VALUESとは対照的 INSERTに付加された式 ここで、データ型はターゲットテーブルから派生します。参照:
- 複数の行を更新するときにNULLタイプをキャストする
複数の行に同じ(firstname, lastname)を付けることができる場合 、最初のINSERTの重複を折りたたむ必要がある場合があります :
...
INSERT INTO sample (firstname, lastname)
SELECT DISTINCT firstname, lastname FROM data
...
CTE dataの代わりに、(一時的な)テーブルをデータソースとして使用できます。 。
これを(firstname, lastname)のUNIQUE制約と組み合わせるのはおそらく理にかなっています。 テーブルとON CONFLICT クエリの句。
関連:
- PostgreSQLでONCONFLICTを使用してRETURNINGを使用するにはどうすればよいですか?
- 関数内のSELECTまたはINSERTは競合状態になりやすいですか?