Эти функции возвращают последнее значение идентификатора, но работают по-разному:
Функция | Область действия | Учитывает триггеры | Безопасность | Конкретная таблица |
---|---|---|---|---|
@@IDENTITY | Все сеансы | Да | Низкая | Нет |
SCOPE_IDENTITY() | Текущая область видимости | Нет | Высокая | Нет |
IDENT_CURRENT() | Указанная таблица | Н/Д | Средняя | Да |
Возвращает последнее значение IDENTITY, сгенерированное в любом таблице текущего сеанса, включая сработавшие триггеры.
INSERT INTO Orders (CustomerID) VALUES ('ALFKI');
SELECT @@IDENTITY AS LastID; -- Может вернуть ID из триггера
Проблема: Если после вашего INSERT сработает триггер, который тоже вставляет данные в таблицу с IDENTITY, вы получите не тот ID.
Возвращает последнее значение IDENTITY, сгенерированное в текущей области видимости (ваш запрос или хранимая процедура), игнорируя триггеры.
INSERT INTO Orders (CustomerID) VALUES ('ALFKI');
SELECT SCOPE_IDENTITY() AS LastID; -- Вернет ID из Orders
Рекомендуется использовать всегда, если нужно получить ID только что вставленной записи.
Возвращает последнее значение IDENTITY, сгенерированное для конкретной таблицы в любом сеансе.
SELECT IDENT_CURRENT('Orders') AS LastOrderID; -- Последний ID в таблице Orders
Особенности:
SCOPE_IDENTITY() - в 95% случаев:
@@IDENTITY - почти никогда (только если нужно значение из триггера)
IDENT_CURRENT() - для административных задач:
CREATE TRIGGER tr_OrderDetails
ON Orders AFTER INSERT
AS
BEGIN
INSERT INTO OrderLogs (OrderID, LogDate)
SELECT OrderID, GETDATE() FROM inserted;
END;
-- Тестовый запрос
INSERT INTO Orders (CustomerID) VALUES ('ALFKI');
SELECT
@@IDENTITY AS [@@IDENTITY], -- Вернет ID из OrderLogs
SCOPE_IDENTITY() AS [SCOPE_IDENTITY], -- Вернет ID из Orders
IDENT_CURRENT('Orders') AS [Orders ID],
IDENT_CURRENT('OrderLogs') AS [Logs ID];
В многопользовательской среде:
@@IDENTITY
и SCOPE_IDENTITY()
возвращают значения только вашего сеансаIDENT_CURRENT()
может вернуть значение, сгенерированное другим пользователемВсе три функции работают мгновенно, так как:
@@IDENTITY
и SCOPE_IDENTITY()
берут значения из памятиIDENT_CURRENT()
делает быстрый lookup в системных таблицахРезюмируем: для получения ID только что вставленной записи всегда используйте SCOPE_IDENTITY()
. @@IDENTITY
опасен из-за триггеров, а IDENT_CURRENT()
полезен для административных задач, но не для работы с конкретными вставками.