SCOPE_IDENTITY (Transact-SQL)
Возвращает последнее значение идентификатора, вставленное в столбец идентификаторов в той же области. Областью является модуль, что подразумевает хранимую процедуру, триггер, функцию или пакет. Таким образом, две инструкции принадлежат одной и той же области, если они находятся в одной и той же хранимой процедуре, функции или пакете.
Синтаксис
SCOPE_IDENTITY()
Типы возвращаемых данных
numeric(38,0)
Замечания
Функции SCOPE_IDENTITY, IDENT_CURRENT и @@IDENTITY идентичны друг другу, поскольку возвращают значения, вставленные в столбцы идентификаторов.
Функция IDENT_CURRENT не ограничена областью действия и сеансом, но ограничена указанной таблицей. Функция IDENT_CURRENT возвращает значение, созданное для указанной таблицы в любом сеансе и области. Дополнительные сведения см. в разделе IDENT_CURRENT (Transact-SQL).
Функции SCOPE_IDENTITY и @@IDENTITY возвращают последние значения идентификатора, созданные в таблицах во время текущего сеанса. Однако функция SCOPE_IDENTITY возвращает значения, вставленные только в рамках текущей области, тогда как действие функции @@IDENTITY не ограничивается никакими областями.
Например, существует две таблицы, T1 и T2, и для таблицы T1 определен триггер INSERT. Когда в таблицу T1 вставляется строка, триггер срабатывает и добавляет строку в таблицу T2. В этом сценарии используются две области: вставка в таблицу T1 и вставка триггером в таблицу T2.
Допуская, что столбец идентификаторов имеется в обеих таблицах, T1 и T2, функции @@IDENTITY и SCOPE_IDENTITY вернут разные значения в конце инструкции INSERT в таблице T1. Функция @@IDENTITY возвращает значение столбца идентификаторов, добавленное в текущем сеансе последним во всех областях. Это значение, вставленное в таблицу T2. Функция SCOPE_IDENTITY() возвратит значение IDENTITY, вставленное в таблицу T1. Это было последним добавлением, произошедшим в заданной области. Функция SCOPE_IDENTITY() вернет значение NULL, если функция была вызвана до того, как какая-либо инструкция INSERT была выполнена для столбца идентификаторов в этой области.
Неудачно завершившиеся инструкции и транзакции могут изменить текущий идентификатор таблицы и создать пропуски в значениях столбца идентификаторов. Для значения идентификатора никогда не производится откат, несмотря на то, что транзакция, пытавшаяся вставить в таблицу значение, не была зафиксирована. Например, если инструкция INSERT привела к ошибке из-за нарушения ограничения IGNORE_DUP_KEY, текущее значение идентификатора для таблицы все равно увеличивается.
Примеры
А. Применение инструкций @@IDENTITY и SCOPE_IDENTITY с триггерами
В следующем примере показано создание двух таблиц, TZ и TY, и триггера INSERT для таблицы TZ. Когда в таблицу TZ добавляется строка, триггер (Ztrig) срабатывает и добавляет строку в таблицу TY.
USE tempdb
GO
CREATE TABLE TZ (
Z_id int IDENTITY(1,1)PRIMARY KEY,
Z_name varchar(20) NOT NULL)
INSERT TZ
VALUES ('Lisa')
INSERT TZ
VALUES ('Mike')
INSERT TZ
VALUES ('Carla')
SELECT * FROM TZ
--Result set: This is how table TZ looks.
Z_id Z_name
-------------
1 Lisa
2 Mike
3 Carla
CREATE TABLE TY (
Y_id int IDENTITY(100,5)PRIMARY KEY,
Y_name varchar(20) NULL)
INSERT TY (Y_name)
VALUES ('boathouse')
INSERT TY (Y_name)
VALUES ('rocks')
INSERT TY (Y_name)
VALUES ('elevator')
SELECT * FROM TY
--Result set: This is how TY looks:
Y_id Y_name
---------------
100 boathouse
105 rocks
110 elevator
/*Create the trigger that inserts a row in table TY
when a row is inserted in table TZ*/
CREATE TRIGGER Ztrig
ON TZ
FOR INSERT AS
BEGIN
INSERT TY VALUES ('')
END
/*FIRE the trigger and determine what identity values you obtain
with the @@IDENTITY and SCOPE_IDENTITY functions.*/
INSERT TZ VALUES ('Rosalie')
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
GO
SELECT @@IDENTITY AS [@@IDENTITY]
GO
Ниже приводится результирующий набор.
SCOPE_IDENTITY
4
/*SCOPE_IDENTITY returned the last identity value in the same scope. This was the insert on table TZ.*/
@@IDENTITY
115
/*@@IDENTITY returned the last identity value inserted to TY by the trigger. This fired because of an earlier insert on TZ.*/
Б. Применение инструкций @@IDENTITY и SCOPE_IDENTITY() с репликацией
В следующем примере показано, как использовать системную переменную @@IDENTITY и функцию SCOPE_IDENTITY(), чтобы вставить данные в базу данных, опубликованную для репликации слиянием. Обе таблицы из примера находятся в образце базы данных AdventureWorks. Таблица Person.ContactType не опубликована, а таблица Sales.Customer опубликована. При репликации слиянием в опубликованные таблицы добавляются триггеры. Таким образом, инструкция @@IDENTITY может возвращать значение из вставки в системную таблицу репликации, а не в пользовательскую таблицу.
Максимальное значение идентификатора в таблице Person.ContactType равно 20. При вставке строки в таблицу инструкции @@IDENTITY и SCOPE_IDENTITY() вернут одинаковые значения.
USE AdventureWorks;
GO
INSERT INTO Person.ContactType ([Name]) VALUES ('Assistant to the Manager')
GO
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
GO
SELECT @@IDENTITY AS [@@IDENTITY]
GO
Ниже приводится результирующий набор.
SCOPE_IDENTITY
21
@@IDENTITY
21
Максимальное значение идентификатора в таблице Sales.Customer равно 29483. При вставке строки в таблицу инструкции @@IDENTITY и SCOPE_IDENTITY() вернут различные значения. Инструкция SCOPE_IDENTITY() вернет значение из вставки в пользовательскую таблицу, а инструкция @@IDENTITY — значение из вставки в системную таблицу репликации. Инструкцию SCOPE_IDENTITY() следует применять для приложений, которым требуется доступ к вставленному значению идентификатора.
INSERT INTO Sales.Customer ([TerritoryID],[CustomerType]) VALUES (8,'S')
GO
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
GO
SELECT @@IDENTITY AS [@@IDENTITY]
GO
Ниже приводится результирующий набор.
SCOPE_IDENTITY
29484
@@IDENTITY
89