SCOPE_IDENTITY (Transact-SQL)

Возвращает последнее значение идентификатора, вставленное в столбец идентификаторов в той же области. Областью является модуль, что подразумевает хранимую процедуру, триггер, функцию или пакет. Таким образом, две инструкции принадлежат одной и той же области, если они находятся в одной и той же хранимой процедуре, функции или пакете.

Применимо для следующих объектов: SQL Server (SQL Server 2008 по текущую версию), База данных SQL Windows Azure (С первоначального выпуска по текущий выпуск).

Значок ссылки на раздел Cинтаксические обозначения в 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'),('Mike'),('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'), ('rocks'), ('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(), чтобы вставить данные в базу данных, опубликованную для репликации слиянием. Обе таблицы из примера находятся в образце базы данных AdventureWorks2012 . Таблица Person.ContactType не опубликована, а таблица Sales.Customer опубликована. При репликации слиянием в опубликованные таблицы добавляются триггеры. Таким образом, инструкция @@IDENTITY может возвращать значение из вставки в системную таблицу репликации, а не в пользовательскую таблицу.

Максимальное значение идентификатора в таблице Person.ContactType равно 20. При вставке строки в таблицу @@IDENTITY и SCOPE_IDENTITY() возвращают одно и тоже значение.

USE AdventureWorks2012;
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],[PersonID]) VALUES (8,NULL);
GO
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];
GO
SELECT @@IDENTITY AS [@@IDENTITY];
GO

Ниже приводится результирующий набор.

SCOPE_IDENTITY

29484

@@IDENTITY

89

См. также

Справочник

@@IDENTITY (Transact-SQL)