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

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

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

Кто-нибудь может объяснить, в чем разница и когда я должен использовать каждый из них?

Комментарии к вопросу (4)
Решение
  • @@IDENTITY возвращает последнее значение идентификатора, созданное для любой таблицы в текущей сессии, во всех диапазонах. Вы должны быть осторожны здесь, так как это происходит во всех диапазонах. Вы можете получить значение из триггера, а не из текущего оператора.

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

  • IDENT_CURRENT('tableName') возвращает последнее значение идентификатора, созданное для определенной таблицы в любой сессии и любой области видимости. Это позволяет вам указать, из какой таблицы вы хотите получить значение, в случае, если два вышеуказанных варианта не совсем то, что вам нужно (очень редко). Также, как отметил @Guy Starbuck, "Вы можете использовать это, если хотите получить текущее значение IDENTITY для таблицы, в которую вы не вставляли записи"

  • Пункт OUTPUT оператора INSERT позволит вам получить доступ к каждой строке, которая была вставлена с помощью этого оператора. Поскольку она привязана к конкретному оператору, она более проста, чем другие функции, описанные выше. Однако она немного более многословна (вам потребуется вставить в табличную переменную/временную таблицу и затем запросить ее) и дает результаты даже в сценарии ошибки, когда оператор откатывается назад. Тем не менее, если ваш запрос использует параллельный план выполнения, это единственный гарантированный метод для получения идентичности (если не отключать параллелизм). Однако он выполняется до триггеров и не может быть использован для возврата значений, генерируемых триггерами.

Комментарии (14)

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

например (взято из следующих в 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
Комментарии (7)

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

Возвращает функция@@Identity идентификатор последней вещью, которая была вставлена на ваш клиент's для подключения к базе данных. Большую часть времени это работает нормально, но иногда триггер пойдет и вставить новую строку, что вы Дон'т знаю о, и вы'll получить код с новой строки, а не тот, который вы хотите

`Функция scope_identity () решает эту проблему. Она возвращает идентификатор последнего, что вставить в SQL-код вы отсылается в базу данных. Если триггеры пойти и создать дополнительные строки, они выиграли'т привести к неправильному значению к вам вернулся. Ура

Функция ident_current возвращает последний ID, который был вставлен кем-либо. Если какое-то другое приложение происходит для того, чтобы вставить еще одну строку в unforunate время, вы'll получить идентификатор этой строки вместо одной.

Если вы хотите играть безопасно, всегда использовать функция scope_identity(). Если вы палку с функция@@Identity и кто-то решит добавить триггер позже, все ваш код будет перерыв.

Комментарии (0)

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

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

-- type of this table's 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)
Комментарии (4)

Добавить

SELECT CAST(scope_identity() AS int);

в конце SQL-оператор Insert, затем

NewId = command.ExecuteScalar()

будет получать он.

Комментарии (0)

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

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

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

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

Но, что's что ФВ делает.

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

Комментарии (1)

MSDN

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

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

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

  • IDENT_CURRENT - это функция, принимающая в качестве аргумента таблицу.
  • @@IDENTITY может вернуть путаный результат, если на таблице установлен триггер.
  • SCOPE_IDENTITY - ваш герой в большинстве случаев.
Комментарии (0)

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

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

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

Комментарии (2)

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

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

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

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

Выход

ID
2
3
4
Комментарии (2)

**** Всегда использовать функции scope_identity(), там's никогда не нужно ничего другого.

Комментарии (6)

Создать идентификатор и вставить его в столбец. Затем вы можете легко определить вашу строку с UUID. Вот только 100% рабочим раствором можно реализовать. Все остальные решения слишком сложны и не работают в той же крайние случаи.

Комментарии (0)

После инструкции Insert, вам необходимо добавить это. И убедитесь, что имя таблицы, где данные вводить.Вы получите в текущей строке нет, где строки влияет только сейчас по вашей инструкции Insert.

IDENT_CURRENT('tableName')
Комментарии (3)

Если вы искали последний код добавлена/обновлена, это может быть немного старомодно, но есть много людей, использующих старые версии PHP, до 5.5 если быть более точным. Более подробную информацию можно найти на http://php.net/manual/en/function.mysql-insert-id.php

$last = mysql_insert_id();
Комментарии (1)