数据库实际应用中,我们往往需要得到刚刚插入的标志值来往相关表中写入数据。但我们平常得到的真的是我们需要的那个值么?
有时我们会使用
SELECT @@Identity
来获得我们刚刚插入的值,比如下面的代码
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
代码一:
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
乐观情况下,这样做是没问题的,但如果我们如果先运行下面的代码二创建一个触发器、再运行代码三:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
代码二:
create
table
test2
(
id
int
identity
(
100
,
1
),
content
nvarchar
(
100
)
)
create
trigger
tri_test1_identitytest_I
on
test1after
insert
as
begin
insert
into
test2
select
content
from
inserted
end
代码三:
insert
into
test1(content)
values
(
'
solorez2
'
)
select
@@identity
我们可以看到,此时得到的标识值已经是100多了,很明显,这是表test2的生成的标识值,已经不是我们想要的了。
我们可以看看@@identity的定义:Identity
原来,@@identity返回的是当前事务最后插入的标识值。
这时我们或许会用下面的方法:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
代码四:
insert
into
test1(content)
values
(
'
solorez3
'
)
SELECT
IDENT_CURRENT(
'
test1
'
)
看来结果还比较正确,但如果我们在多次运行代码四的同时运行下面的代码五:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
代码五:
insert
into
test1(content)
values
(
'
solorez3
'
)
waitfor
delay
'
00:00:20
'
SELECT
IDENT_CURRENT(
'
test1
'
)
结果又不是我们想要的了!
再看看IDENT_CURRENT(Tablename) 的定义:IDENT_CURRENT (Tablename)
是返回指定表的最后标识值。
到这里,是该亮出答案的时候了,我们可以使用下面的代码:
<!-- <br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
代码六:
insert
into
test1(content)
values
(
'
solorez3
'
)
SELECT
scope_identity
()
这时,我们无论是添加触发器还是运行并行插入,得到的始终是当前事务的标识值。
scope_identity()的定义:scope_identity ()