MSSQL Try Catch Rollback和Conditional RETURN

时间:2014-08-07 13:10:31

标签: sql sql-server

SET XACT_ABORT ON

BEGIN TRY

    BEGIN TRANSACTION

    UPDATE [Members] SET [Count] = [Count] - 1 WHERE [Count] > 0; 
    **return 0 here if this statement updated 0 rows**

    INSERT INTO [Sessions] ([Name], [Etc]) VALUES ('Test', 'Other')

    COMMIT TRANSACTION

END TRY
BEGIN CATCH

    IF @@TRANCOUNT > 0
    ROLLBACK TRANSACTION;

    RETURN 0

END CATCH

SELECT SCOPE_IDENTITY(); **only return the identity if the first statement updated 1 row and no exceptions occurred.**

使用上面的代码,如果第一个UPDATE更新没有行,有没有办法返回0?如果第一个UPDATE编辑一行并且没有错误发生,我只想要INDENTITY()。这可能吗?

2 个答案:

答案 0 :(得分:2)

您可以使用@@ROWCOUNT来更改号码。这应该有效:

UPDATE [Members] SET [Count] = [Count] - 1 WHERE [Count] > 0; 
IF @@ROWCOUNT = 0
BEGIN
    COMMIT TRANSACTION;
    RETURN;
END;

因为没有更新行,我认为回滚事务将是等效的。

要获取插入的标识值,我建议您学习使用OUTPUT中的INSERT子句(记录为here)。这是一个很好的习惯,虽然语法有点麻烦(你必须定义一个表/表变量来存储插入的值)。它没有竞争条件,它允许您返回多个身份值。

答案 1 :(得分:1)

如果您实际插入,则只读取SCOPE_IDENTITY 这样,您只有一个退出点

BEGIN TRY

    BEGIN TRANSACTION

    UPDATE [Members] SET [Count] = [Count] - 1 WHERE [Count] > 0; 
    IF @@ROWCOUNT = 1
    BEGIN
        INSERT INTO [Sessions] ([Name], [Etc]) VALUES ('Test', 'Other')
        SET @rtn = SCOPE_IDENTITY();
    END
        SET @rtn = 0;

    COMMIT TRANSACTION;
    SELECT @rtn
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
END CATCH