2017-09-22 12 views
-1

同じ環境では、同じSQL Serverテーブルに2つの重複した挿入を避ける必要があります。これを行うためにSQL Serverと重複した挿入防止

、すべての最初の、私はSELECTを実行しよう:たとえば

WITH (UPDLOCK, ROWLOCK) 

:その直後

SELECT * 
FROM Products p WITH (UPDLOCK, ROWLOCK) 
WHERE p.groupId = ?1 AND p.classId = ?2 

上記の選択がで0レコードを返す場合同じ取引私はINSERTステートメントを行います。

このアプローチでは、同じ製品の空のテーブルに重複が防止されますか?p.groupId = ?1 AND p.classId = ?2

いいえ、重複を避けるためにどのように実装する必要がありますか?

+2

UNIQUEインデックスを作成します。 – NEER

+1

'groupIdと' classId' *の組み合わせが一意でなければならない場合、それらはあなたのプライマリキーであるか、またはユニークな制約が適用されている必要があります。この保護を「保証する」他の方法もありますが、フィールド/テーブルに適切な制約を適用することが最善の方法です。 – alroc

+0

あなたの答えをありがとう。私は間違っているかもしれませんが、私はこのアプローチの潜在的な問題を1つ見ています(私を修正してください) - 既存のデータ(これらのgroupIdとclassIdを持つ)の場合に2番目のトランザクションは失敗しますが、新しいレコード - それらを更新するために既存のレコードを使用します。これは、私が2番目のトランザクションが最初のトランザクション完了を待つことを望んでいる理由です。これが私がMS SQL Serverのロック機構を探している理由です。 – alexanoid

答えて

3

テーブルに挿入を行い、複数の行が同じgroupIdとclassIdを持たないようにするには、テーブルの作成でUnique制約を使用することをお勧めします。例えば:あなたは詳細を見つけることができます

ALTER TABLE Products 
ADD CONSTRAINT UC_GroupClassID UNIQUE (groupId, classId) 

CREATE TABLE Products (
    groupId int NOT NULL, 
    classId int NOT NULL, 
    ... 
    CONSTRAINT UC_GroupClassID UNIQUE (groupId, classId) 
); 

別の方法としては、としてテーブルを変更することができますあなたのコメントに基づいて

https://docs.microsoft.com/en-us/sql/relational-databases/tables/create-unique-constraints

https://www.w3schools.com/sql/sql_unique.asp

1

を、レコードがすでに存在するときに更新したい。マージステートメントは、このために設計されています。受信データを一時テーブルまたはテーブル変数に格納し、マージを発行することをお勧めします。

私はここに掲載する予定の例については、このリンクを参照してください。テーブル名と一致基準を変更するだけです。

https://technet.microsoft.com/en-us/library/bb522522(v=sql.105).aspx

MERGE Target AS T 
USING Source AS S 
ON (T.EmployeeID = S.EmployeeID) 
WHEN NOT MATCHED BY TARGET AND S.EmployeeName LIKE 'S%' 
    THEN INSERT(EmployeeID, EmployeeName) VALUES(S.EmployeeID, S.EmployeeName) 
WHEN MATCHED 
    THEN UPDATE SET T.EmployeeName = S.EmployeeName 
WHEN NOT MATCHED BY SOURCE AND T.EmployeeName LIKE 'S%' 
    THEN DELETE 
OUTPUT $action, inserted.*, deleted.*; 
関連する問題