Бөлісу құралы:


@@IDENTITY (Transact-SQL)

Применимо к:SQL ServerБаза данных SQL AzureУправляемый экземпляр SQL AzureБаза данных SQL в Microsoft Fabric

@@IDENTITY — системная функция, которая возвращает последнее вставленное значение тождества.

Соглашения о синтаксисе Transact-SQL

Синтаксис

@@IDENTITY  

Типы возвращаемых данных

numeric(38,0)

Замечания

INSERTПосле завершения @@IDENTITY инструкции массового SELECT INTOкопирования содержит последнее значение удостоверения, созданное инструкцией.

  • Если оператор не затрагивает таблицы с столбцами идентичности, @@IDENTITY возвращает NULL.
  • Если вставлять несколько строк, генерируя несколько тождественных значений, @@IDENTITY возвращается последнее сгенерированное значение идентичности.
  • Если оператор запускает один или несколько триггеров, которые выполняют вставки, генерирующие значения идентичности, вызов @@IDENTITY сразу после этого оператора возвращает последнее значение идентичности, сгенерированное триггерами.
  • Если триггер запускается после действия вставки в таблицу с столбцом удостоверений, а триггер вставляется в другую таблицу, которая не имеет столбца удостоверения, @@IDENTITY возвращает значение удостоверения первой вставки. Значение @@IDENTITY не возвращается к предыдущему параметру, если INSERT не удается выполнить инструкцию или SELECT INTO массовую копию, или если транзакция откатится.

Неудачно завершившиеся инструкции и транзакции могут изменить текущий идентификатор таблицы и создать пропуски в значениях столбца идентификаторов. Значение удостоверения никогда не откатывается, даже если транзакция, которая пыталась вставить значение в таблицу, не фиксируется. Например, если INSERT инструкция завершается ошибкой IGNORE_DUP_KEY из-за нарушения, текущее значение удостоверения таблицы по-прежнему увеличивается.

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

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

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

Область @@IDENTITY функции — текущий сеанс на локальном сервере, на котором он выполняется. Эту функцию нельзя применить к удаленным или связанным серверам. Чтобы получить значение удостоверения на другом сервере, выполните хранимую процедуру на этом удаленном или связанном сервере и выполните хранимую процедуру (которая выполняется в контексте удаленного или связанного сервера), соберите значение удостоверения и верните его в вызывающее соединение на локальном сервере.

Репликация может повлиять на @@IDENTITY значение, так как она используется в триггерах репликации и хранимых процедурах. @@IDENTITY Не является надежным индикатором последнего созданного пользователем удостоверения, если столбец является частью статьи репликации. Можно использовать синтаксис SCOPE_IDENTITY() функций вместо @@IDENTITY. Дополнительные сведения см. в разделе SCOPE_IDENTITY (Transact-SQL).

Примечание.

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

Примеры

А. Получение значения последнего вставленного удостоверения

Следующий пример вставляет строку в таблицу, содержащую столбец идентификаторов (LocationID), и применяет функцию @@IDENTITY для отображения значения идентификатора, используемого в новой строке.

USE AdventureWorks2022;
GO

--Display the value of LocationID in the last row in the table.
SELECT MAX(LocationID) FROM Production.Location;
GO

INSERT INTO Production.Location (Name, CostRate, Availability, ModifiedDate)
VALUES ('Damaged Goods', 5, 2.5, GETDATE());
GO

SELECT @@IDENTITY AS 'Identity';
GO

--Display the value of LocationID of the newly inserted row.
SELECT MAX(LocationID) FROM Production.Location;
GO

В. Вставка родительских и дочерних строк с помощью @@IDENTITY

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

-- Create sample tables
CREATE TABLE dbo.Orders (
    OrderID int IDENTITY(1, 1) PRIMARY KEY,
    CustomerName nvarchar(100) NOT NULL,
    OrderDate datetime NOT NULL DEFAULT GETDATE()
);

CREATE TABLE dbo.OrderDetails (
    DetailID int IDENTITY(1, 1) PRIMARY KEY,
    OrderID int NOT NULL REFERENCES dbo.Orders(OrderID),
    ProductName nvarchar(100) NOT NULL,
    Quantity int NOT NULL
);
GO

-- Insert a parent row and capture its identity
INSERT INTO dbo.Orders (CustomerName, OrderDate)
VALUES ('Contoso Ltd', GETDATE());

DECLARE @NewOrderID int = @@IDENTITY;

-- Insert child rows using the captured parent identity
INSERT INTO dbo.OrderDetails (OrderID, ProductName, Quantity)
VALUES (@NewOrderID, 'Widget A', 10);

INSERT INTO dbo.OrderDetails (OrderID, ProductName, Quantity)
VALUES (@NewOrderID, 'Widget B', 5);

-- Verify the results
SELECT o.OrderID, o.CustomerName, d.ProductName, d.Quantity
FROM dbo.Orders o
INNER JOIN dbo.OrderDetails d ON o.OrderID = d.OrderID
WHERE o.OrderID = @NewOrderID;
GO

Примечание.

В рабочем коде используйте SCOPE_IDENTITY() вместо @@IDENTITY этого шаблона. Если триггер запускается в Orders таблице и выполняет вставку в другую таблицу с столбцом удостоверений, @@IDENTITY возвращает значение удостоверения триггера вместо Orders значения удостоверения. SCOPE_IDENTITY() возвращает только значение удостоверения из текущей области.

С. Понимание разницы между @@IDENTITY и SCOPE_IDENTITY

В следующем примере показано, как @@IDENTITY и SCOPE_IDENTITY() может возвращать различные значения при использовании триггеров.

CREATE TABLE dbo.Products (
    ProductID int IDENTITY(1, 1) PRIMARY KEY,
    ProductName nvarchar(100) NOT NULL
);

CREATE TABLE dbo.ProductAudit (
    AuditID int IDENTITY(1000, 1) PRIMARY KEY,
    ProductID int NOT NULL,
    AuditAction nvarchar(50) NOT NULL,
    AuditDate datetime NOT NULL DEFAULT GETDATE()
);
GO

-- Create a trigger that inserts into ProductAudit
CREATE TRIGGER trg_ProductInsert
ON dbo.Products
AFTER INSERT
AS
BEGIN
    INSERT INTO dbo.ProductAudit (ProductID, AuditAction)
    SELECT ProductID, 'INSERT'
    FROM inserted;
END;
GO

-- Insert a product and compare identity values
INSERT INTO dbo.Products (ProductName) VALUES ('Test Product');

SELECT @@IDENTITY AS [@@IDENTITY],
       SCOPE_IDENTITY() AS [SCOPE_IDENTITY];
GO

В этом примере SCOPE_IDENTITY() возвращается ProductID из Products таблицы (текущая область), а @@IDENTITY возвращается AuditID из ProductAudit таблицы (область триггера). Для большинства сценариев приложений это более безопасный вариант, SCOPE_IDENTITY() так как он не влияет на действие триггера.