Получить идентификатор после INSERT в SQL Server в многопоточной среде? - PullRequest
6 голосов
/ 12 октября 2010

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

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

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

Ответы [ 8 ]

12 голосов
/ 12 октября 2010
SELECT SCOPE_IDENTITY()

Используйте это после вашего оператора вставки, и он вернет вам идентификатор вставленного в вашу область. Вы можете присвоить это переменной или вернуть в выходном параметре.

3 голосов
/ 12 октября 2010

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

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

2 голосов
/ 12 октября 2010

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

Например:

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;

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

2 голосов
/ 12 октября 2010

Попробуйте это

@@identity

ниже образца кода

strSQL = "INSERT INTO tablename (name) VALUES (@name);SELECT @@Identity"
SQLCommand.CommandText = strSQL
Id = SQLCommand.ExecuteScalar()
0 голосов
/ 28 мая 2013

см. SQL Server - Возвращаемое значение после INSERT

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');
0 голосов
/ 12 октября 2010

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

0 голосов
/ 12 октября 2010

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

Вам нужно будет использовать, как уже упоминалось, SCOPE_IDENTITY(), а не @@IDENTITY, так как SCOPE_IDENTITY() возвращает значение идентификатора для текущей области выполнения, когда @@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 голосов
/ 12 октября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...