为何使用@@identity、SCOPE_IDENTITY() 均获取不到id值?

sunworld 2008-10-31 11:17:08
我在一个项目里使用了SQL Server 2000,本希望使用@@identity、或SCOPE_IDENTITY() 来获取最新插入数据的主键值,前面一直有几个表是很好的能获取,但是到了后面复杂一点的功能上,就一直不能正确获取主键值,不管使用哪个返回ID的函数,调用时总是返回的空值。

但事实上数据确实已经新增了,程序上也没有在新增数据的时候报错,现在只能使用“Select ID From t_table order by ID DESC”这样的查询来返回新增的ID,但是我知道这样的查询可能会一下子提取很多的数据,影响到软件整体运行效率。

请问一下,我遇到的这个问题,使用@@identity、或SCOPE_IDENTITY() 获取不到最新插入的记录的ID值,是由于什么原因产生的?该如何解决?

...全文
471 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zincy 2008-11-07
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 dobear_0922 的回复:]
我在一个项目里使用了SQL Server 2000,本希望使用@@identity、或SCOPE_IDENTITY() 来获取最新插入数据的主键值,


------------
2000里面只能用@@identity,在2005里才有SCOPE_IDENTITY()
[/Quote]

不要乱说,SCOPE_IDENTITY() 2000能用的
rucypli 2008-10-31
  • 打赏
  • 举报
回复
@@IDENTITY 函数的作用域是执行该函数的本地服务器上的当前会话。此函数不能应用于远程或链接服务器。若要获得其他服务器上的标识值,请在远程服务器或链接服务器上执行存储过程,并使(在远程或链接服务器的环境中执行的)该存储过程收集标识值,并将其返回本地服务器上的发出调用的连接。
rucypli 2008-10-31
  • 打赏
  • 举报
回复
@@IDENTITY 和 SCOPE_IDENTITY 可以返回当前会话中的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。
rucypli 2008-10-31
  • 打赏
  • 举报
回复
Select top 1 ID From t_table order by ID DESC
fcuandy 2008-10-31
  • 打赏
  • 举报
回复
查会话及作用域
幸运的意外 2008-10-31
  • 打赏
  • 举报
回复
是不是出了作用域的原因呀?超出了回话范围就有肯那个导致取得不到相关表的自增列的值.
-狙击手- 2008-10-31
  • 打赏
  • 举报
回复
8楼的可能性比较大
zjcxc 元老 2008-10-31
  • 打赏
  • 举报
回复
另外, 如果你在插入后如果还有插入其他非identity列的表的操作, 则取不到 identity 列值
例如下面的

DECLARE @t1 TABLE(
id int IDENTITY,
col int
);
DECLARE @t2 TABLE(
col int
);

INSERT @t1 VALUES(1);
SELECT @@IDENTITY, SCOPE_IDENTITY()
INSERT @t2 VALUES(1);
SELECT @@IDENTITY, SCOPE_IDENTITY()
Yang_ 2008-10-31
  • 打赏
  • 举报
回复
把@@identity、或SCOPE_IDENTITY() 放在insert语句后马上执行,中间不能有其他语句

检查所涉及的表有无触发器,触发器对@@identity有影响,但是对SCOPE_IDENTITY() 没有影响的
tianhuo_soft 2008-10-31
  • 打赏
  • 举报
回复
重新生成一下 ID列

把ID列删除,然后在增加进来
就重新生成ID列了
dawugui 2008-10-31
  • 打赏
  • 举报
回复
三种方法:

IDENT_CURRENT('table_name') 返回为任何会话和任何作用域中的特定表最后生成的标识值。

@@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。

SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值。


如果是单用户:
Select top 1 ID From t_table order by ID DESC
Select max(ID) From t_table
dobear_0922 2008-10-31
  • 打赏
  • 举报
回复
我在一个项目里使用了SQL Server 2000,本希望使用@@identity、或SCOPE_IDENTITY() 来获取最新插入数据的主键值,


------------
2000里面只能用@@identity,在2005里才有SCOPE_IDENTITY()
水族杰纶 2008-10-31
  • 打赏
  • 举报
回复
@@IDENTITY和SCOPE_IDENTITY和IDENT_CURRENT的区别
1,@@IDENTITY是得到当前会话的所有范围的最后插入的IDENTITY值
2,SCOPE_IDENTITY是得到当前会话的当前范围的最后插入的IDENTITY值
3,IDENT_CURRENT是得到指定表的最后插入的IDENTITY值,与会话、范围无关。

因为在插入和得到IDENTITY值之间可能会有其它的事情发生,但是你只想得到我刚才插入的IDENTITTY值,只有使用SCOPE_IDENTITY函数才行。

以下是测试SQL
(1)
USE pubs
DROP TABLE t6
DROP TABLE t7
GO
CREATE TABLE t6(id int IDENTITY)
CREATE TABLE t7(id int IDENTITY(100,1))
GO
CREATE TRIGGER t6ins ON t6 FOR INSERT
AS
BEGIN
INSERT t7 DEFAULT VALUES
END
GO
--end of trigger definition

SELECT * FROM t6
--id is empty.

SELECT * FROM t7
--id is empty.

--Do the following in Session 1
INSERT t6 DEFAULT VALUES
declare @i int
set @i = 0
while @i < 20000
begin
set @i = @i + 1
print @i
end

SELECT @@IDENTITY as "@@IDENTITY0"
/*Returns the value 100, which was inserted by the trigger.*/

SELECT SCOPE_IDENTITY() 'SCOPE_IDENTITY()0'
/* Returns the value 1, which was inserted by the
INSERT stmt 2 statements before this query.*/

SELECT IDENT_CURRENT('t7') 'IDENT_CURRENT(t7)0'
/* Returns value inserted into t7, i.e. in the trigger.*/

SELECT IDENT_CURRENT('t6') 'IDENT_CURRENT(t6)0'
/* Returns value inserted into t6, which was the INSERT statement 4 stmts before this query.*/

-- Do the following in Session 2
SELECT @@IDENTITY "@@IDENTITY1"
/* Returns NULL since there has been no INSERT action
so far in this session.*/

SELECT SCOPE_IDENTITY() 'SCOPE_IDENTITY()1'
/* Returns NULL since there has been no INSERT action
so far in this scope in this session.*/

SELECT IDENT_CURRENT('t7') 'IDENT_CURRENT(t7)1'
/* Returns the last value inserted into t7.*/


当在执行while @i < 20000
begin
set @i = @i + 1
print @i
end这个地方的时候,就可以用


INSERT t6 DEFAULT VALUES
INSERT t7 DEFAULT VALUES
select * from t6
select * from t7来进行操作数据库

等到全部执行完了,你就会发现只有SCOPE_IDENTITY列永远是1
hyde100 2008-10-31
  • 打赏
  • 举报
回复

2008年04月24日 星期四 17:26SQL Server 2000中,有三个比较类似的功能:他们分别是:SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值。

IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值。IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回为任何会话和作用域中的特定表所生成的值。
@@IDENTITY 返回为当前会话的所有作用域中的任何表最后生成的标识值。
SCOPE_IDENTITY 返回为当前会话和当前作用域中的任何表最后生成的标识值

SCOPE_IDENTITY 和 @@IDENTITY 返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY 只返回插入到当前作用域中的值;@@IDENTITY 不受限于特定的作用域。


例如,有两个表 T1 和 T2,在 T1 上定义了一个 INSERT 触发器。当将某行插入 T1 时,触发器被激发,并在 T2 中插入一行。此例说明了两个作用域:一个是在 T1 上的插入,另一个是作为触发器的结果在 T2 上的插入。


假设 T1 和 T2 都有 IDENTITY 列,@@IDENTITY 和 SCOPE_IDENTITY 将在 T1 上的 INSERT 语句的最后返回不同的值。


@@IDENTITY 返回插入到当前会话中任何作用域内的最后一个 IDENTITY 列值,该值是插入 T2 中的值。


SCOPE_IDENTITY() 返回插入 T1 中的 IDENTITY 值,该值是发生在相同作用域中的最后一个 INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用 SCOPE_IDENTITY() 函数,则该函数将返回 NULL 值。


而IDENT_CURRENT('T1') 和 IDENT_CURRENT('T2') 返回的值分别是这两个表最后自增的值。


zjcxc 元老 2008-10-31
  • 打赏
  • 举报
回复
检查你的id列的自增属性有没有丢失

34,588

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧