2017-06-16 52 views
0

我有两个相同的表,除了一个具有标识列而另一个没有。相反,第二个表使用第一个表中的标识列的值。当我将一条记录插入到第一个表中时,我想我会插入第二个表作为触发器。我似乎无法得到正确的语法。如何检索插入触发器中的标识列值SQL Server

从标识列@EDVisitId返回空值。

ALTER TRIGGER [dbo].[trgInserterrEDVisitOriginal] ON [dbo].[errEDVisit] 
AFTER INSERT 
AS 


--Name: Bob Avallone 
--Date: 6-15-2017 
-- 
-- The purpose of this trigger is to insert a record into errEDVisitOriginal 
-- whenever a new errEDVisit is inserted. 

--XXXXXXXXXX 



    declare @EDVisitId int 
    declare @SubmissionControlID INT 


Select @EDVisitId = EDVisitID from inserted 
SELECT @SubmissionControlID = SubmissionControlID from Inserted 


    Begin 

Insert Into errEDVisitOriginal (EDVisitId, SubmissionControlID) 

VALUES (@EDVisitId, @SubmissionControlID) 



End 
+1

你的触发器有一个主要的缺陷!它假定只有一行插入。每次操作时,sql server中的触发器都会触发一次。因为这种触发器需要基于设置而不是基于标量的。 –

+0

而不是在触发器中这样做,你应该有一个插入程序。在那个过程中,你会想要使用OUTPUT子句,这样你就可以捕获所有新插入的标识值。 –

回答

0

你只需要SCOPE_IDENTITY()

选择@EDVisitId = SCOPE_IDENTITY()

+0

这会获得身份,但它会延续触发器的缺陷本质。 –

+0

@SeanLange哟指的是什么缺陷?你说的唯一的一个问题是你的文章中的问题是“从标识列@EDVisitId返回空值”。当您使用scope_identity()设置ID时,那么问题是什么? – AaronLS

+0

因为在触发器中使用像这样的标量变量,假定只有一行被插入。这不是触发器在sql server中的工作方式。触发器需要基于设置。如果你坚持标量值的触发器,你必须添加一个循环。啊!! –

0

您可以使用SCOPE_IDENTITY获得最后插入的ID从第一个表放到一个变量,然后插入第二张桌子。

https://docs.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql

+0

在插入多行时,在触发器中使用像这样的变量不是一个好方法。 –

+1

我没有意识到他在触发器上使用它。我会在存储过程中执行插入而不是触发器。 –

0

虽然有意复制信息的决定是值得怀疑,你有很大的过度思考的代码。只是:

if exists (select * from inserted) 
insert dbo.errEDVisitOriginal (EDVisitId, SubmissionControlID) 
select EDVisitId, SubmissionControlID from inserted; 
1

感谢您的所有建议。我放弃了触发器的想法。相反,我只需将第一张表中的新记录插入第二张。见下文。

Insert errEDVisitOriginal(EdVisitId, SubmissionControlID) 
    Select EdVisitId, SubmissionControlID 
    from errEDVisit where SubmissionControlID = @SubmissionControlID