私は特にあなたの文章に対処するための別の考えを提案したいと思います:「私はので、バッチから単一の行がテーブルに存在するかどうかを確認したいので、私は彼らのすべてを知っていた挿入します。」
あなたは「バッチ」に挿入することで物事を効率的にしていますが、その後、存在チェックを実行して一度に1つのレコードをチェックしていますか?これは私には直観に反するようです。したがって、「挿入は常にバッチで行われる」と言った場合、1つの挿入ステートメントで複数のレコードを挿入していることになります。PostgresがACIDに準拠していることを理解する必要があります。1つのinsertステートメントで複数のレコード(データのバッチ)を挿入する場合、いくつかのレコードが挿入されたかどうかを確認する必要はありません。ステートメントは成功するか、失敗します。すべてのレコードが挿入されるか、何も挿入されません。
一方、C#コードがループなどで単に「個別の」setステートメントを実行している場合、これが「バッチ」であるということを頭に入れておくと、実際には「バッチ」と記述すべきではありません。挿入は常にバッチで行われます。」「バッチ」と呼ばれるもののその部分が実際には挿入されない可能性があるため、チェックの必要性を感じるという事実は、これが事実であることを強く示唆しています。この場合、より根本的な問題があります。1つの挿入で複数のレコードを実際に挿入するようにパラダイムを変更し、個々のレコードがそれを作成したかどうかを確認する必要はありません。
この例を考えてみましょう:
CREATE TABLE temp_test (
id SERIAL PRIMARY KEY,
sometext TEXT,
userid INT,
somethingtomakeitfail INT unique
)
-- insert a batch of 3 rows
;;
INSERT INTO temp_test (sometext, userid, somethingtomakeitfail) VALUES
('foo', 1, 1),
('bar', 2, 2),
('baz', 3, 3)
;;
-- inspect the data of what we inserted
SELECT * FROM temp_test
;;
-- this entire statement will fail .. no need to check which one made it
INSERT INTO temp_test (sometext, userid, somethingtomakeitfail) VALUES
('foo', 2, 4),
('bar', 2, 5),
('baz', 3, 3) -- <<--(deliberately simulate a failure)
;;
-- check it ... everything is the same from the last successful insert ..
-- no need to check which records from the 2nd insert may have made it in
SELECT * FROM temp_test
これは実際、Postgresqlだけでなく、ACID準拠のDBのパラダイムです。言い換えれば、「バッチ」の概念を修正して、最初に行ごとのチェックを行わなくても済むようにした方がよいでしょう。