2016-09-28 15 views
0

2つの列IDとdescを持つdbo.mtestUniqueというテーブルがあります。このテーブルにデータを挿入する2つのプロセスがあります。同じ時間に、重複する値を挿入してユニークなインデックスに違反することを避けるにはどうすればよいですか?SQL Server 2014 - 並列プロセス一意インデックスを持つテーブルに同じ値を挿入

は存在しません。左結合は機能しません。

CREATE TABLE mtestUnique 
(
    id INT , 
    [DESC] varchar(50), 
    UNIQUE([DESC]) 
) 

、その後、SSMS上の2つの異なるクエリに次のスクリプトを実行します:あなたは、テストデータベースにテーブルを作成することができ、これを複製する

SET XACT_ABORT ON; 
DECLARE @time VARCHAR(50) 

WHILE (1=1) 
BEGIN 
    IF OBJECT_ID('tempdb..#t') IS NOT NULL 
     DROP TABLE #t 

    SELECT @time = CAST(DATEPART(HOUR , GETDATE()) AS VARCHAR(10)) + ':' + RIGHT('00' +CAST(DATEPART(MINUTE , GETDATE())+1 AS VARCHAR(2)),2) 

    SELECT MAX(id) + 1 id , 'test' + @time [DESC] 
     INTO #t 
    FROM dbo.mtestUnique 

    -- to insert as exact same time 
    WAITFOR TIME @time 

     INSERT INTO dbo.mtestUnique 
       (id, [DESC]) 
     SELECT * 
     FROM #t t 
     WHERE NOT EXISTS (
         SELECT 1 
         FROM dbo.mtestUnique u 
         WHERE u.[DESC] = t.[Desc] 

         ) 

END 

私はTRANに挿入しても運はありません。

ご協力いただきありがとうございます。

+0

ID列で[ID](https://msdn.microsoft.com/en-us/library/ms186775.aspx)を使用できますか? – SMM

+0

どのように役立つでしょうか? – user3951476

+0

独自のdescが必要な場合は、時間だけでなくユニークなdescを作成します。たとえば、を使用します。 NEWID()または現在のsession_ID +時間。 – Anton

答えて

0

唯一の制約違反を防止する唯一の方法は、列に重複値を挿入しないことです。一意の制約がある場合、重複した説明を挿入しようとするとエラーがスローされますが、挿入しようとする説明が制御されません。

これで、固有の識別子が必要な場合は、IDを使用することを強くお勧めします。それを自動で疑わしい整数に設定し、手動で挿入しないでください。説明を入力するだけで、重複を避けるためにSQL ServerによってIDが設定されます。

+0

これは単なるサンプルです。ユーザー名とユーザー名の表がユニークであるため、ユニークな制約が設定されていて、異なるプロセスがその表にuserNameを挿入しようとしています。この場合、IDや識別子は必要ありません。
"一意制約違反を防止する唯一の方法は、列に重複値を挿入しないことです。"
それは私が存在しない理由です。 – user3951476

+0

はい、一意のユーザー名だけが必要な場合は、一意の制約が必要です。ただし、主キーではなく、少なくともインデックスに対するインデックスであれば、ユーザー名は他のテーブルと結合されています。 あなたは何の問題を見ていますか?挿入を試行中に制約違反でクエリの1つが失敗しますか? @timeまで待つ場合でも、挿入物の1つがテーブルにロックされているので、実際にはパラレルに挿入されません。 –

+0

まったく、1つのプロセスがロックを持つと思われ、2番目のプロセスは最初のプロセスが完了するまで待つ必要があります。挿入すると、「存在しません」と評価され、ユニーク制約に違反することなく行が挿入されますが、それは異なっています。私は、SQL Serverは、テーブル上のIUロックを求めると、両方のプロセスで "存在しない"ステートメントを評価し、挿入ステップでは1つのプロセスがUにロックをエスカレートし、2番目のプロセスはこのステップでロックを待機すると思います。 – user3951476

関連する問題