Ответ 1
Нет необходимости в отдельном SELECT...
INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');
Это также работает для столбцов без идентификатора (например, GUID)
Я пытаюсь получить значение ключа после инструкции INSERT. Пример: У меня есть таблица с именами атрибутов и идентификатором. id - это сгенерированное значение.
INSERT INTO table (name) VALUES('bob');
Теперь я хочу вернуть идентификатор на том же шаге. Как это делается?
Мы используем Microsoft SQL Server 2008.
Нет необходимости в отдельном SELECT...
INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');
Это также работает для столбцов без идентификатора (например, GUID)
Используйте SCOPE_IDENTITY()
, чтобы получить новое значение ID
INSERT INTO table (name) VALUES('bob');
SELECT SCOPE_IDENTITY()
INSERT INTO files (title) VALUES ('whatever');
SELECT * FROM files WHERE id = SCOPE_IDENTITY();
Является самой безопасной ставкой, так как существует известная проблема с конфликтом OUTPUT Clause на таблицах с триггерами. Делает это довольно ненадежным, даже если ваша таблица в настоящее время не имеет триггеров - кто-то, добавив один в линию, нарушит ваше приложение. Время Бомбы.
См. статью msdn для более глубокого объяснения:
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 год, вам не повезло.
Вы можете использовать scope_identity, чтобы выбрать идентификатор строки, которую вы только что вставили в переменную, а затем просто выберите любые столбцы, которые вы хотите, из этой таблицы, где id = идентификатор, полученный вами из scope_identity
См. здесь информацию MSDN http://msdn.microsoft.com/en-us/library/ms190315.aspx
@@IDENTITY - это системная функция, которая возвращает значение идентификатора последней вставленной строки.
Вот как я использую 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)
* Параметр в строке соединения иногда важен. * Расположение параметра поставщика может сломать курсор набора записей после добавления строки. Мы видели это поведение с поставщиком SQLOLEDB.
После добавления строки поля строки недоступны, ЕСЛИ поставщик не указан как первый параметр в строке подключения. Когда поставщик находится где угодно в строке соединения, кроме первого параметра, вновь вставленные поля строк недоступны. Когда мы переместили Провайдера к первому параметру, поля строк волшебным образом появились.
После ввода в таблицу с столбцом идентификатора вы можете ссылаться на @@IDENTITY, чтобы получить значение: http://msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx