在单个事务中插入和使用插入的ID是否安全

时间:2017-09-21 04:39:53

标签: sql sql-server tsql

在单个事务中插入并使用插入的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

1 个答案:

答案 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()?