2016-08-30 7 views
0

はのは、SQL Server 2012の中に以下のような簡単な表を想定してみましょう:C#でselect文で自動インクリメントされた主キーの最後の値を取得するのは安全ですか?

CREATE TABLE Person (
    Id INT IDENTITY(1, 1) PRIMARY KEY, 
    Name NVARCHAR(50) 
) 

そして、次のように対応するクラス:

public class Person 
{ 
    public int Id {get; set;} 
    public string Name {get; set;} 
} 

は、以下のCreatePerson方法(擬似コード)今考えてみましょう:

public static Person CreatePerson(string name) { 
    ... 
    DB.Execute("INSERT INTO Person(Name) VALUES (name)", name); 
    int lastId = DB.Get("SELECT MAX(Id) FROM Person"); 
    return new Person {Id = lastId, Name=name}; 
} 

このメソッドは、dbに新しい人物行を作成し、新しいPersonオブジェクトを作成してから、作成されたsuデータベースが生成したIDを格納するように指定されています。

は、次のSELECT文を使用して最後に生成されたIdを取得するのが安全かどうか(並行処理の観点から)ですか?

SELECT MAX(Id) FROM Person 

私は次のシナリオを懸念しています:

  1. USER Aがperson 2
  2. USERが最後の読み込み挿入person 1
  3. ユーザーBを挿入しますイドはイドだと思うユーザAとユーザBは、ここでデータベースへの2つの別々のクエリを処理するスレッドを指す。なお

+0

を使用してlastIdを得ることができますか?分散システムでは、そのような情報は簡単に時代遅れになる可能性があります。 – xxbbcc

+0

ユーザーAに挿入された人物(またはこの場合は人物)を見たい場合は、その人物を挿入したユーザーを示すフィールドをテーブルに追加することができます。あなたの 'SELECT'に合った' WHERE'文を追加すると、 'MAX(Id)'に問題はないはずです。 –

+2

[挿入された行のIDを取得するための最良の方法?](http://stackoverflow.com/questions/42648/best-way-to-get-identity-of-insertedrow) – Igor

答えて

4

特定のスコープの人が挿入した最後のID値を取得する場合は、Scope_Identity()を使用します。

特定の表に最後のID値を挿入する場合は、@@identityを使用できます。

特定のテーブルの現在のID値を取得する場合は、Ident_Current ('Yourtablename')を使用します。

3

ありません、それは安全ではありません、あなたはデータの挿入のために、この手順を使用して何をしようとするscopre_Identity機能

create PROCEDURE Your_procedure_for_insert 
@Name  VARCHAR(50), 
@lastID  INT OUTPUT 
AS 
BEGIN 
SET NOCOUNT ON; 

INSERT INTO Person 
      (
      Name     
      ) 
VALUES 
      (
      @Name 
      ); 

SET @lastID = SCOPE_IDENTITY(); 

END; 
+0

ありがとうZaynul Abadin Tuhinしかし、私はC#で手続き型ロジックを扱うことに興味があります。 – Chedy2149

+0

このリンクはあなたに役立つと思います。https://msdn.microsoft.com/en-us/library/bb399357(v=vs.110).aspx –