Как SCOPE_IDENTITY возвращает значение null, если @@IDENTITY нет?

После выполнения вставки я либо выбираю SCOPE_IDENTITY, либо @@IDENTITY.

SCOPE_IDENTITY возвращает значение null, но @@IDENTITY - нет.

Я не понимаю, как это возможно.

Можете ли вы подумать о причине, почему это происходит?

Ответы

Ответ 1

Вот один пример того, как SCOPE_IDENTITY() будет иметь значение null, но @@IDENTITY будет иметь значение:

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

FYI, существует известная ошибка с SCOPE_IDENTITY(): https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811

Лучше всего использовать идентификаторы - использовать OUTPUT INTO, он может захватывать набор идентификаторов и не подлежит ошибке SCOPE_IDENTITY():

declare @x table (tableID int identity not null primary key, datavalue varchar(10))
declare @y table (tableID int, datavalue varchar(10))

INSERT INTO @x values ('aaaa')
INSERT INTO @x values ('bbbb')
INSERT INTO @x values ('cccc')
INSERT INTO @x values ('dddd')
INSERT INTO @x values ('eeee')


INSERT INTO @x
    (datavalue)
    OUTPUT INSERTED.tableID, INSERTED.datavalue     --<<<<OUTPUT INTO SYNTAX
    INTO @y                                         --<<<<OUTPUT INTO SYNTAX
SELECT
    'value='+CONVERT(varchar(5),dt.NewValue)
    FROM (SELECT id as NewValue from sysobjects where id<20) dt
    ORDER BY dt.NewValue


select * from @x
select * from @y

Ответ 2

KM ударил ноготь по голове:

  • @@IDENTITY дает вам вставленное последнее значение IDENTITY - независимо от того, где была вставлена ​​таблица (подумайте триггеры, например, в таблицы аудита! Или даже каскад триггеров....)

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

Ответ 3

SCOPE_IDENTITY также вернет NULL, когда вставка находится на sp_executesql, поскольку вы больше не находитесь в области INSERT!

Ответ 4

Я нашел это на MSDN:

Функция SCOPE_IDENTITY() вернет нулевое значение, если функция вызывается до того, как какие-либо операторы INSERT в столбец идентификатора появятся в области.

Вы можете прочитать здесь: http://msdn.microsoft.com/en-us/library/ms190315.aspx

Ваш код SQL будет очень полезен.

Ответ 5

create procedure spAddEmployee
@Name nvarchar(50),
@Gender nvarchar(20),
@Salary int,
@EmployeeId int out
as
begin 
declare @maxEmpId int
select @maxEmpId = MAX(Id) from tblEmployee
insert into tblEmployee values(@maxEmpId+1,@Name,@Gender,@Salary)
Select @EmployeeId = SCOPE_IDENTITY();
end

Здесь также я получаю ноль, но я все еще в поле зрения, почему??