data
という名前のテーブルに挿入したいアイテムを含む文字列ベクトルがありますfoos
。の要素の一部がdata
テーブルに既に存在する可能性があるため、それらに注意する必要があります。
私が使用しているソリューションは、data
ベクトルを仮想テーブルに変換することから始まりますold_and_new
。old
次に、 に既に存在する要素を含む仮想テーブルを作成しfoos
ます。new
次に、本当に新しい要素で仮想テーブルを構築します。最後に、新しい要素を table に挿入しますfoos
。
WITH old_and_new AS (SELECT unnest ($data :: text[]) AS foo),
old AS (SELECT foo FROM foos INNER JOIN old_and_new USING (foo)),
new AS (SELECT * FROM old_and_new EXCEPT SELECT * FROM old)
INSERT INTO foos (foo) SELECT foo FROM new
これは非並行設定では正常に機能しますが、並行スレッドが同じ新しい要素を同時に挿入しようとすると失敗します。分離レベルを に設定することでこれを解決できることはわかっていますがserializable
、それは非常に手間がかかります。
この問題を解決できる他の方法はありますか?INSERT
エラーを無視しても安全であることをPostgreSQLに伝える方法があれば...