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

Я пытаюсь получить значение ключа после инструкции INSERT. Пример: У меня есть таблица с именами атрибутов и идентификатором. id - это сгенерированное значение.

    INSERT INTO table (name) VALUES('bob');

Теперь я хочу вернуть идентификатор на том же шаге. Как это делается?

Мы используем Microsoft SQL Server 2008.

Ответ 1

Нет необходимости в отдельном SELECT...

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

Это также работает для столбцов без идентификатора (например, GUID)

Ответ 3

INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

Является самой безопасной ставкой, так как существует известная проблема с конфликтом OUTPUT Clause на таблицах с триггерами. Делает это довольно ненадежным, даже если ваша таблица в настоящее время не имеет триггеров - кто-то, добавив один в линию, нарушит ваше приложение. Время Бомбы.

См. статью msdn для более глубокого объяснения:

http://blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx

Ответ 4

Entity Framework выполняет нечто похожее на gbn-ответ:

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');

SELECT t.[CustomerID]
FROM @generated_keys AS g 
   JOIN dbo.Customers AS t 
   ON g.Id = t.CustomerID
WHERE @@ROWCOUNT > 0

Результаты вывода сохраняются во временной переменной таблицы, а затем выбираются обратно клиенту. Должны знать о получении:

Вставки

могут генерировать более одной строки, поэтому переменная может содержать более одной строки, поэтому вам может быть возвращено более одного ID

Я понятия не имею, почему EF будет внутренне присоединяться к эфемерной таблице обратно к реальной таблице (при каких обстоятельствах эти два не совпадают).

Но это то, что делает EF.

Только SQL Server 2008 или более новый. Если это 2005 год, вам не повезло.

Ответ 5

Вы можете использовать scope_identity, чтобы выбрать идентификатор строки, которую вы только что вставили в переменную, а затем просто выберите любые столбцы, которые вы хотите, из этой таблицы, где id = идентификатор, полученный вами из scope_identity

См. здесь информацию MSDN http://msdn.microsoft.com/en-us/library/ms190315.aspx

Ответ 6

@@IDENTITY - это системная функция, которая возвращает значение идентификатора последней вставленной строки.

Ответ 7

Вот как я использую OUTPUT INSERTED при вставке в таблицу, которая использует идентификатор в столбце идентификации в SQL Server:

'myConn is the ADO connection, RS a recordset and ID an integer
Set RS=myConn.Execute("INSERT INTO M2_VOTELIST(PRODUCER_ID,TITLE,TIMEU) OUTPUT INSERTED.ID VALUES ('Gator','Test',GETDATE())")
ID=RS(0)

Ответ 8

* Параметр в строке соединения иногда важен. * Расположение параметра поставщика может сломать курсор набора записей после добавления строки. Мы видели это поведение с поставщиком SQLOLEDB.

После добавления строки поля строки недоступны, ЕСЛИ поставщик не указан как первый параметр в строке подключения. Когда поставщик находится где угодно в строке соединения, кроме первого параметра, вновь вставленные поля строк недоступны. Когда мы переместили Провайдера к первому параметру, поля строк волшебным образом появились.