2010-10-12 2 views
6

Как я могу получить идентификатор после INSERT в SQL Server?Получить идентификатор после INSERT в SQL Server в многопоточном режиме?

Для моей вставки, я использую context.ExecuteStoreCommand()

Предупреждения: У меня есть многопоточное приложение на который вставляет «в то же время» некоторые данные в одной таблице.

ответ

11
SELECT SCOPE_IDENTITY() 

Используйте это после вставки заявления и вернет вам личность вставлен в рамки. Вы можете назначить это переменной или вернуть ее в выходной параметр.

+0

Что такое область действия? 2 потока - разные области? –

+0

да, они есть. проверьте http://msdn.microsoft.com/en-us/library/ms190315.aspx подробную документацию для SCOPE_IDENTITY – Numenor

+0

, как SCOPE_IDENTITY() отличается от идентификатора @@, сам SCOPE_IDENTITY() возвращает идентификатор @@ ... и в мой ответ, я вернул идентификатор @@ после вставки ... – RameshVel

0

Я думаю, что вы можете написать хранимую процедуру, которая имеет параметр ввода/вывода, а затем захватить значение из параметра.

2

Попробуйте

@@identity 

ниже примере кода

strSQL = "INSERT INTO tablename (name) VALUES (@name);SELECT @@Identity" 
SQLCommand.CommandText = strSQL 
Id = SQLCommand.ExecuteScalar() 
+0

Это не будет поточно. – Numenor

+0

@Numenor, как это не потокобезопасно ... ?? – RameshVel

+0

@Numenor - о чем вы говорите?Это отлично потокобезопасно, поскольку обе команды выполняются в одном запросе. –

3

Для этого сценария следует использовать Scope_Identity(). Это вернет Identity для текущей области. @@Identity возвращает последний вставленный идентификатор.

Посмотрите на Scope Identity on MSDN - есть примеры того, как @@Identity будет возвращать неверные значения по сравнению с использованием Scope_Identity

2

Альтернативного метода реализации является использование положения языка T-SQL OUTPUT.

Например:

create table #tmpTable 
(
    ID int identity(1,1) not null primary key, 
    SomeValue varchar(20) not null 
); 

insert #tmpTable 
output INSERTED.ID 
values('SomeTextData') 

drop table #tmpTable; 

С общей точки зрения дизайна решения, которое я защитил бы, что вы смотрите, чтобы обернуть вставки логики в хранимую процедуру (возвращая вставленный идентификатор записи), что вы звоните из исходного кода приложения ,

0

Я уверен, что вы захотите использовать метод ObjectContext.ExecuteStoreQuery, если вам нужно значение идентификации, а не ObjectContext.ExecuteStoreCommand.

Вы должны будете использовать, как уже упоминалось SCOPE_IDENTITY(), а не @@IDENTITY как SCOPE_IDENTITY() возвращает значения идентификатора для сферы исполнения currente @@IDENTITY Тогда как «является системной функцией, которая возвращает последнее вставленное значение идентичности.»

Что-то вроде этого следует сделать трюк:

using(var context = GetAContextThatsReadyToUse()) 
{ 
    var valueForColumn1 = 5; 
    var result = ExecuteStoreQuery<int>("INSERT INTO table1 (Column1) VALUES ({0});SELECT SCOPE_IDENTITY()", valueForColumn1); 

    foreach(var item in result) 
    { 
     // Should only return one result, which is the identity value inserted by ExecuteStoreQuery 
     Console.WriteLine(item); 
    } 
} 
0

Я имел много ситуаций, когда что-то вроде 100 процессов писал в одной таблице одновременно. Я не использовал SCOPE_IDENTITY(), но обертывал всю вставку/идентификацию в транзакцию, и не было никаких проблем с этим подходом.

Смежные вопросы