Лучший способ получить личность вставленной строки?

Каков наилучший способ получить IDENTITY вставленной строки?

Я знаю о @@IDENTITY и IDENT_CURRENT и SCOPE_IDENTITY, но не понимаю плюсы и минусы, связанные с каждым.

Может кто-нибудь объяснит различия и когда я буду использовать их?

+1038
03 сент. '08 в 21:32
источник поделиться
11 ответов
+1339
03 сент. '08 в 21:38
источник

Я считаю, что самый безопасный и самый точный метод извлечения вставленного id будет использовать предложение вывода.

например (взято из следующей статьи MSDN)

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO
+169
20 мая '11 в 14:43
источник
другие ответы

Связанные вопросы


Похожие вопросы

Я говорю то же самое, что и другие ребята, поэтому все правильно, я просто пытаюсь сделать это более понятным.

@@IDENTITY возвращает идентификатор последней вещи, которая была вставлена ​​вашим клиентским соединением в базу данных.
В большинстве случаев это работает нормально, но иногда срабатывает триггер и вставляет новую строку, о которой вы не знаете, и вы получите идентификатор из этой новой строки, а не тот, который вы хотите

SCOPE_IDENTITY() решает эту проблему. Он возвращает идентификатор последней вещи, которую вы вставили в код SQL, который вы отправили в базу данных. Если триггеры идут и создают дополнительные строки, они не будут возвращать неправильное значение. Hooray

IDENT_CURRENT возвращает последний идентификатор, который был вставлен кем-либо. Если какое-либо другое приложение случайно введет другую строку в нерабочее время, вы получите идентификатор этой строки, а не ваш.

Если вы хотите играть в нее безопасно, всегда используйте SCOPE_IDENTITY(). Если вы придерживаетесь @@IDENTITY, и кто-то решает добавить триггер позже, весь ваш код сломается.

+103
03 сент. '08 в 21:44
источник

Самый лучший (читаемый: самый безопасный) способ получить личность вновь вставленной строки - это использовать предложение output:

create table TableWithIdentity
           ( IdentityColumnName int identity(1, 1) not null primary key,
             ... )

-- type of this table column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )

insert TableWithIdentity
     ( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
     ( ... )

select @IdentityValue = (select ID from @IdentityOutput)
+62
29 апр. '13 в 7:22
источник

Добавить

SELECT CAST(scope_identity() AS int);

до конца вашего встраиваемого sql-оператора, затем

NewId = command.ExecuteScalar()

получит его.

+22
30 мар. '15 в 18:25
источник

Когда вы используете Entity Framework, он внутренне использует метод OUTPUT для возврата вновь вставленного значения идентификатора

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');

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

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

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

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

Этот метод (OUTPUT) доступен только на SQL Server 2008 или новее.

+15
04 нояб. '16 в 15:05
источник

MSDN

@@IDENTITY, SCOPE_IDENTITY и IDENT_CURRENT являются схожими функциями, поскольку они возвращают последнее значение, вставленное в столбец IDENTITY таблицы.

@@IDENTITY и SCOPE_IDENTITY вернут последнее значение идентификации, сгенерированное в любой таблице текущего сеанса. Однако SCOPE_IDENTITY возвращает значение только в пределах текущей области; @@IDENTITY не ограничивается определенной областью.

IDENT_CURRENT не ограничивается областью и сеансом; он ограничен указанной таблицей. IDENT_CURRENT возвращает значение идентификатора, сгенерированное для конкретной таблицы, в любом сеансе и в любой области. Для получения дополнительной информации см. IDENT_CURRENT.

  • IDENT_CURRENT - это функция, которая принимает таблицу в качестве аргумента.
  • @@IDENTITY может возвращать запутанный результат, когда у вас есть триггер в таблице
  • SCOPE_IDENTITY - ваш герой большую часть времени.
+14
03 сент. '08 в 21:37
источник

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

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

IDENT_CURRENT (имя_таблицы) - это последняя идентификация, вставленная независимо от соединения или области видимости. Вы можете использовать это, если хотите получить текущее значение IDENTITY для таблицы, в которую вы не ввели запись.

+13
03 сент. '08 в 21:42
источник

Я не могу говорить с другими версиями SQL Server, но в 2012 году вывод напрямую работает просто отлично. Вам не нужно беспокоиться о временной таблице.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)

Кстати, этот метод также работает при вставке нескольких строк.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
    (...),
    (...),
    (...)

Выход

ID
2
3
4
+11
06 июн. '18 в 16:58
источник

ВСЕГДА используйте scope_identity(), НИКОГДА ничего не нужно.

+8
09 окт. '09 в 20:35
источник

После вашего заявления о вставки вам нужно добавить это. И Удостоверьтесь в имени таблицы, где данные вставляются. Вы получите текущую строку, где строка, затронутая только теперь вашим оператором insert.

IDENT_CURRENT('tableName')
0
31 дек. '17 в 6:04
источник

Посмотрите другие вопросы по меткам или Задайте вопрос