我在桌子上有一个触发器而不是触发器。触发器工作正常但我们有一个应用程序,用户可以通过UI对表执行批量更新。在这种情况下,select scope_identity返回null。当用户通过UI执行更新时,我运行sql profiler来查看后台发生了什么,我得到了这个:
insert into Table(column1, column2,....)
values (value1, value2,.....)
go
select scope_identity()
go
在这种情况下,内部而不是触发器定义的scope_identity()返回正确的值,但上面语句中的scope_identity()返回null,此时应用程序抛出错误。我想这是因为插入发生在触发器内部,不属于上述scope_identity的范围。 我知道这个问题可以通过使用触发器代替触发器来解决但是该表包含ntext列,这将阻止我在触发后使用。将ntext列转换为nvarchar(max)对我来说也不是一个选项。 关于如何使select scope_identity()返回正确值的任何想法?
提前致谢。
答案 0 :(得分:0)
好的我可以重新解决您的问题,并提供解释和解决方案。
use tempdb
go
set ansi_nulls on
set quoted_identifier on
go
create table sampletable (
ix int identity primary key,
column1 nvarchar(50),
column2 nvarchar(50)
)
go
go
/* First with no trigger - works fine */
insert sampletable(column1, column2)
select 'a', 'b'
select @@identity, scope_identity(), ident_current('sampletable')
select * from sampletable
go
/* create instead trigger */
create trigger dbo.sampletrigger on sampletable
instead of insert
as
begin
insert into sampletable(column1, column2) select column1, column2 from inserted
end
go
/* Now scope_identity() is null */
insert sampletable(column1, column2)
select 'a', 'b'
select @@identity, scope_identity(), ident_current('sampletable')
select * from sampletable
go
go
go
drop table sampletable
Scope_identity()
为null,因为您没有在当前作用域中插入具有标识的行。
Scope_identity()
是当前批次中当前范围中插入的最后一个标识。触发器是一个单独的范围,因此在触发器之外它是null。
无论范围如何,您都需要使用@@identity
这是批量中插入的最后一个标识。
您无法使用ident_current('sampletable')
,这是在该特定表上的任何批处理和任何会话中插入的最后一个标识,因为这可能会因其他并发用户而获得更改。