在单个事务中插入并使用插入的ID是否安全
如下。
我想知道的是什么时候会创建Table1
的新条目?提交交易之后还是之前?
这个Id能否在Table2中访问?
BEGIN TRY
BEGIN TRANSACTION
INSERT INTO dbo.Table1([Name])
values('Name')
DECLARE @Id int
SET @Id = SCOPE_IDENTITY()
INSERT INTO dbo.TableNam2(UId,FeatureId)
VALUES(NEWID (), @Id)
COMMIT
END TRY
BEGIN CATCH
ROLLBACK
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT
@ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState)
END CATCH
答案 0 :(得分:3)
是的,这是安全的,因为您使用了SCOPE_IDENTITY()
。如果您使用了@@IDENTITY
,那么情况并非如此,例如,可以从dbo.Table1
上的触发器插入中获取新的身份。
无论事务是提交还是回滚,都会在执行插入后立即生成新标识。
是的,您可以使用该值插入dbo.Table2
。没问题。
根据我的经验提出几点建议:
正如@Nick指出的那样,如果插入因任何原因失败,可能会留下空白,这会消耗一个永远不会出现在表中的标识值。对于在事务外部失败的插入也是如此。永远不能保证身份是连续的。
如果有人在第一次插入后无意中添加了另一条声明而未注意到使用SCOPE_IDENTITY()
,则可能会出现意外结果。我喜欢将SET
语句附加到插入的末尾,以便在您获取新标识之前插入某些内容三思而后行
尝试这样的事情:
declare @Id int
insert into dbo.Table1([Name]) values ('Name')
set @Id = SCOPE_IDENTITY()
-- Code continues here ...
进一步阅读 - What is the difference between Scope_Identity(), Identity(), @@Identity, and Ident_Current()?