scope_identity由于而不是触发器而返回dbnull

时间:2012-05-22 18:02:12

标签: sql

我在桌子上有一个触发器而不是触发器。触发器工作正常但我们有一个应用程序,用户可以通过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()返回正确值的任何想法?

提前致谢。

1 个答案:

答案 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'),这是在该特定表上的任何批处理和任何会话中插入的最后一个标识,因为这可能会因其他并发用户而获得更改。