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

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

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

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

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

10 ответов


нет необходимости в отдельном выборе...

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

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


использовать SCOPE_IDENTITY() чтобы получить новое значение ID

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

SELECT SCOPE_IDENTITY()

http://msdn.microsoft.com/en-us/library/ms190315.aspx


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

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

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

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


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

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

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

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

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

только SQL Server 2008 или новее. Если это 2005, то вам не повезло.


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


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

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


вот как я использую вставленный вывод при вставке в таблицу, которая использует ID в качестве столбца идентификатора в 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)

к инструкции insert можно добавить оператор select. Целое число myInt = Вставьте в table1 (FName) значения ('Fred'); выберите Scope_Identity(); Это вернет значение идентификатора при выполнении масштабирования.


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

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


после вставки в таблицу со столбцом идентификатора вы можете ссылаться на @@IDENTITY, чтобы получить значение: http://msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx