UNIQUEまたはPRIMARYKEY制約で表現できない条件でレコードの一意性を保証する必要がある場合は、存在のチェックと挿入が1つのトランザクションで実行されていることを確認する必要があります。これは、次のいずれかで実現できます。
- チェックと挿入を実行する1つのSQLステートメントを使用する(3番目のオプション)
- 適切な分離レベルでトランザクションを使用する
ただし、4番目の方法があります。これは、コードをより適切に構造化し、レコードのバッチを一度に処理する必要がある状況でも機能させるのに役立ちます。 TABLE変数または一時テーブルを作成し、そこに挿入する必要のあるすべてのレコードを挿入してから、この変数に基づいてINSERT、UPDATE、およびDELETEステートメントを記述できます。
以下は、このアプローチを示す(擬似)コードです。
-- Logic to create the data to be inserted if necessary
DECLARE @toInsert TABLE (idCol INT PRIMARY KEY,dataCol VARCHAR(MAX))
INSERT INTO @toInsert (idCol,dataCol) VALUES (1,'row 1'),(2,'row 2'),(3,'row 3')
-- Logic to insert the data
INSERT INTO realTable (idCol,dataCol)
SELECT TI.*
FROM @toInsert TI
WHERE NOT EXISTS (SELECT 1 FROM realTable RT WHERE RT.dataCol=TI.dataCol)
多くの場合、このアプローチを使用すると、TSQLコードが読みやすくなり、リファクタリングして単体テストを適用できるようになります。