UPSERTの実装は非常に複雑で、同時書き込みアクセスに対して安全です。初期開発時にログとして機能したこのPostgresWikiを見てください。 Postgresハッカーは、「除外された」行をRETURNING
に含めないことを決定しました。 Postgres9.5の最初のリリースの条項。彼らは次のリリースのために何かを組み込むかもしれません。
これは、あなたの状況を説明するためのマニュアルの重要なステートメントです:
RETURNING
の構文 listは、SELECT
の出力リストと同じです。 。 正常に挿入または更新された行のみが返されます。 たとえば、行がロックされているが、ON CONFLICT DO UPDATE ... WHERE
が原因で更新されていない場合 句の条件が満たされていないため、行は返されません。
大胆な強調鉱山。
単一行の場合 挿入するには:
同じテーブルへの同時書き込み負荷なし
WITH ins AS (
INSERT INTO users(name)
VALUES ('new_usr_name') -- input value
ON CONFLICT(name) DO NOTHING
RETURNING users.id
)
SELECT id FROM ins
UNION ALL
SELECT id FROM users -- 2nd SELECT never executed if INSERT successful
WHERE name = 'new_usr_name' -- input value a 2nd time
LIMIT 1;
テーブルに同時書き込み負荷がかかる可能性がある
代わりにこれを検討してください(単一行の場合) INSERT
):
- 関数内のSELECTまたはINSERTは競合状態になりやすいですか?
行のセットを挿入するには :
-
PostgreSQLでONCONFLICTを使用してRETURNINGを使用するにはどうすればよいですか?
-
RETURNING from INSERT ...ONCONFLICTに除外された行を含める方法
3つすべてに非常に詳細な説明があります。