我有以下表格:
tbl_workshop
id int identity
Name nvarchar(10)
Address nvarchar(40)
tbl_workshop_temp
id int identity
code int
InsUpkey smallint
我有以下陈述
insert into tbl_workshop
(Name,Address)
values('x','y')
select @@identity -- My problem is here
我也有以下触发器插入:
create trigger InsertedWorkshop
on tbl_workshop
for insert
as
insert into tbl_workshop_temp
(code,InsUpKey)
select id,1
from inserted
当select @@identity
语句运行时,我在id
中插入tbl_workshop_temp
而不是id
中插入的tbl_workshop
我知道我必须使用scope_identity
,但我无法更改代码。我只能改变我的触发器。
我现在应该怎么做?请帮帮我。
答案 0 :(得分:4)
你不能欺骗@@identity
返回一些不同的值。您可以做的是从IDENTITY
中删除tbl_workshop_temp
属性,并且该列中没有递增值(只使用与tbl_workshop
相同的ID),完全删除列,或者以这种方式在触发器中填充它(这意味着它只适用于一行):
DECLARE @id INT;
SELECT @id = MAX(id) + 1
FROM dbo.tbl_workshop_temp WITH (UPDLOCK, HOLDLOCK); -- important
insert into dbo.tbl_workshop_temp
(id,code,InsUpKey)
select @id,id,1
from inserted;
使用SQL Server 2005及更高版本,您可以更加聪明 - 您可以更改上面的内容,以便使用ROW_NUMBER()
来处理多行,或者您可以使用INSTEAD OF TRIGGER
代替(不需要双关语)并简单地更改插入语句的顺序。但是对于SQL Server 2000,您的选择确实有限......
答案 1 :(得分:1)
有关每个身份选择的工作原理,请参阅this question。您将不得不更改初始INSERT
的代码以修复此问题。 @@identity
始终从会话中获取最后一个ID,并且由于触发器是同一会话的一部分,因此您必须更改在应用程序中拾取ID的方式。
答案 2 :(得分:0)
您可以在插入的行中选择where where子句,如此
SELECT ID_FIRST_TABLE FROM TRIGGERED_TABLE WHERE TRIGGERED_ID = @@Identity