数据库实际应用中,我们往往需要得到刚刚插入的标志值来往相关表中写入数据。但我们平常得到的真的是我们需要的那个值么? 有时我们会使用 SELECT @@Identity 来获得我们刚刚插入的值,比如下面的代码
代码一:
use tempdb if exists (select * from sys.objects where object_id = object_id(N'[test1]') and type in (N'u')) drop table [test1] go create table test1 ( id int identity(1,1), content nvarchar(100) ) insert into test1 (content) values ('solorez') select @@identity 乐观情况下,这样做是没问题的,但如果我们如果先运行下面的代码二创建一个触发器、再运行代码三:
代码二:
create table test2 ( id int identity(100,1), content nvarchar(100) ) create trigger tri_test1_identitytest_I on test1 after insert as begin insert into test2 select content from inserted end
代码三:
insert into test1 (content) values ('solorez2') select @@identity
我们可以看到,此时得到的标识值已经是100多了,很明显,这是表test2的生成的标识值,已经不是我们想要的了。 我们可以看看@@identity的定义:Identity 原来,@@identity返回的是当前事务最后插入的标识值。 这时我们或许会用下面的方法:
代码四:
insert into test1 (content) values ('solorez3') SELECT IDENT_CURRENT('test1')
看来结果还比较正确,但如果我们在多次运行代码四的同时运行下面的代码五:
代码五:
insert into test1 (content) values ('solorez3') waitfor delay '00:00:20' SELECT IDENT_CURRENT('test1')
结果又不是我们想要的了! 再看看IDENT_CURRENT(Tablename) 的定义:IDENT_CURRENT(Tablename) 是返回指定表的最后标识值。 到这里,是该亮出答案的时候了,我们可以使用下面的代码:
代码六:
insert into test1 (content) values ('solorez3') SELECT scope_identity()
这时,我们无论是添加触发器还是运行并行插入,得到的始终是当前事务的标识值。 scope_identity()的定义:scope_identity() PS:这是在添加触发器时,一个存储过程报错发现的问题,感觉有一定的普遍性,希望能给大家带来帮助。 (责任编辑:admin) |