项目中有一个存储过程sp,向表A插入一条数据,表有INSTEAD OF INSERT触发器,在触发器中,有一条语句是向表A中插入的语句:
INSERT [A] SELECT I.[TCW_PKey] , I.[TCE_PKey] .... FROM [Inserted] AS I ....
现在想在触发器中的这条语句之后立即得到插入的主键值,用IDENT_CURRENT,那么并发插入会出问题,所以想用SCOPE_IDENTITY或者@@IDENTITY, 可是纠结的是, 在本地结果是正确的,也就是插入到[A]的主键值可是在服务器上却是其他表的主键,跟踪单用户运行也结果不正确,是表C的主键,哎,理论上这关表C什么事啊?当然,是在存储过程sp中在插入表A之前向表C插入了数据.
现在我的问题是,是数据库配置还是选项或者SP补丁影响了SCOPE_IDENTITY或者@@IDENTITY返回值?还是其他问题?希望有经验的朋友提示一下,感激不尽
INSERT [A] SELECT I.[TCW_PKey] , I.[TCE_PKey] .... FROM [Inserted] AS I ....
现在想在触发器中的这条语句之后立即得到插入的主键值,用IDENT_CURRENT,那么并发插入会出问题,所以想用SCOPE_IDENTITY或者@@IDENTITY, 可是纠结的是, 在本地结果是正确的,也就是插入到[A]的主键值可是在服务器上却是其他表的主键,跟踪单用户运行也结果不正确,是表C的主键,哎,理论上这关表C什么事啊?当然,是在存储过程sp中在插入表A之前向表C插入了数据.
现在我的问题是,是数据库配置还是选项或者SP补丁影响了SCOPE_IDENTITY或者@@IDENTITY返回值?还是其他问题?希望有经验的朋友提示一下,感激不尽
解决方案 »
- 请问这个SQL语句该怎么写?
- 求存储过程
- ASP+access转换MSSQL需要多少费用
- 如何在触发器执行出错时,让update继续执行
- 如何将一个表中所有null替换为''?
- 请问如何查询某表中最近有被更新的记录并随机抽取10条
- 急急急!最大内存使用值写成了1M结果整个数据都打不开了
- 创建一个名为 "person" 的表,此表有三列。列名是 "FirstName", "LastName" 以及 "Age":
- 菜鸟求一简单SQL查询语句
- 通过拨号建立连接后查询分析其无法连接服务器,在线等候!!
- 求按 每周的8:30到 本周最后一天的 8:30 统计语句
- 急急??!!sql2000 连不上局域网的另一个sql服务器??
if object_id('tb')is not null drop table tb
go
create table tb(ID int identity,[name] varchar(10))
insert tb
output inserted.ID
select 'test'
insert tb
output inserted.ID
select 'test'
/*
ID
-----------
1ID
-----------
2*/
if object_id('tb')is not null drop table tb
go
create table tb(ID int identity,[name] varchar(10))
declare @t table(ID int)
insert tb
output inserted.ID into @t
select 'test'
insert tb
output inserted.ID into @t
select 'test'
select * from @t
/*
ID
-----------
1
2
*/
@@IDENTITY 和 SCOPE_IDENTITY 将返回在当前会话的所有表中生成的最后一个标识值。但是,SCOPE_IDENTITY 只在当前作用域内返回值,而 @@IDENTITY 不限于特定的作用域。IDENT_CURRENT 不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT 返回任何会话和任何作用域中为特定表生成的标识值。有关更多信息,请参见 IDENT_CURRENT。楼主看一下是不是这个问题,你应该要用的IDENT_CURRENT,这个才仅限于表,其它的是所有表生成的标识
/*
对于@@identity而言,它返回的是当前会话中任何作用域内的最后插入的一个标识值
对于scope_identity()而言,它返回的是当前作用域内插入的标识值
*/
create table t1
(
id int identity(1,1),
col int
)
create table t2
(
id int identity(100,1),
col int
)
create trigger tg_t1 on t1
for insert
as
insert into t2 select col from inserted
go
insert into t1 select 2
select @@identity,scope_identity() 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ws_hgo/archive/2009/02/10/3872714.aspx
我在本地是正常的,服务器上不知道为什么就不正确?相同的存储过程和触发器
(
id int identity(1,1),
col int
)
create table t2
(
id int identity(100,1),
col int
)
create trigger tg_t1 on t1
for insert
as
insert into t2 select col from inserted
go
insert into t1 select 3
select @@identity,scope_identity()
--------------------------------------- ---------------------------------------
101 2(1 行受影响)select * from t2id col
----------- -----------
100 2
101 3(2 行受影响)
select * from t1
id col
----------- -----------
1 2
2 3(2 行受影响)看我上面的代码
scope_identity()是当前insert into t1 select 3
返回的ID
而这个@@identity
是所有表中最后返回的也就是触发器中针对t2插入的值
101 3
要不你贴出你的整个语句看看吧
Z_id int IDENTITY(1,1)PRIMARY KEY,
Z_name varchar(20) NOT NULL)INSERT TZ
VALUES ('Lisa')
INSERT TZ
VALUES ('Mike')
INSERT TZ
VALUES ('Carla')
CREATE TABLE TY (
Y_id int IDENTITY(100,5)PRIMARY KEY,
Y_name varchar(20) NULL)INSERT TY (Y_name)
VALUES ('boathouse')
INSERT TY (Y_name)
VALUES ('rocks')
INSERT TY (Y_name)
VALUES ('elevator')SELECT * FROM TY
--Result set: This is how TY looks:
CREATE TRIGGER Ztrig
ON TZ
FOR INSERT AS
BEGIN
INSERT TY VALUES ('')
END
INSERT TY VALUES ('bbbbb')INSERT TZ VALUES ('gggggg')SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]
GO
SELECT @@IDENTITY AS [@@IDENTITY]
GO
SCOPE_IDENTITY 返回为当前会话和当前作用域中的某个表生成的最新标识值。
LZ @@identity是所有作用域以下是联机的注释在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含语句生成的最后一个标识值。如果语句未影响任何包含标识列的表,则 @@IDENTITY 返回 NULL。如果插入了多个行,生成了多个标识值,则 @@IDENTITY 将返回最后生成的标识值。如果语句触发了一个或多个触发器,该触发器又执行了生成标识值的插入操作,那么,在语句执行后立即调用 @@IDENTITY 将返回触发器生成的最后一个标识值。如果对包含标识列的表执行插入操作后触发了触发器,并且触发器对另一个没有标识列的表执行了插入操作,则 @@IDENTITY 将返回第一次插入的标识值。出现 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或者事务被回滚的情况时,@@IDENTITY 值不会恢复为以前的设置。
在触发器里面:
INSERT [A] SELECT I.[TCW_PKey] , I.[TCE_PKey] .... FROM [Inserted] AS I ....
SET @PKEY = SCOPE_IDENTITY(); -- 或者 SET @PKEY = @@IDENTITY ; 这样写没错吧? 本机执行也是正确的,可是在服务器上执行就不正确,是C表的主键.
为什么?
我早几天试过了..在tempdb里面执行结果和本地一样..,我现在去真实db中试试
SCOPE_IDENTITY,但是必须跟在insert语句后面,中间不能有任何其他语句
或者麻烦点,用IDENT_CURRENT( 'table_name' ),注意不同地方的table_name是不同的,也要跟在insert语句后面
我当然知道跟在INSERT后面.原因是,本地服务器没有并发,而实际服务器有并发
同一个会话,还并发? SCOPE_IDENTITY 不是当前会话的当前作用域么?
看看A表上有什么触发器,这些触发器有没有向C插入数据。
你去问下他吧
http://hi.csdn.net/fcuandy
但你也知道,这样阻止并发,用户一多,被阻止的人就多了现在改成允许并发插入,从而需要改成SCOPE_IDENTITY ,可以本地可以,在服务器上就是错误的值,IDENT_CURRENT是正确,但是并发插入肯定有问题
INSERT [A] SELECT I.[TCW_PKey] , I.[TCE_PKey] .... FROM [Inserted] AS I ....
现在想在触发器中的这条语句之后立即得到插入的主键值,