SQL 使用自定义模板的服务器事务

SQL Server transaction with custom template

我会问一个基本的问题,如果某些条件得到验证,我会使用本机事务来回滚一堆 tables。

我真的必须检查有多少更新结果基于某些存储过程,这些存储过程从输入报告填充的 tables 中收集数据,更改太少或太多都意味着回滚,因为我们将拒绝报告。我会用 T-SQL 的本地事务来实现这个功能,这是我的伪想法:

CREATE PROCEDURE mytest 
AS
BEGIN
    BEGIN TRANSACTION
    BEGIN TRY
        EXEC foo
        EXEC bar
        EXEC baz
    END TRY

    IF true
       COMMIT TRANSACTION
    ELSE
       ROLLBACK TRANSACTION
END

当然,这不起作用,因为关键字 'IF' 附近的语法不正确,可能是因为它不是使用事务的正确方法。

修复了这个我会考虑如何计算 table 的变化,如果需要使用临时 table 或者我是否可以使用一些 SQL 功能。我正在搜索文档或示例,但我没有找到任何东西。

有什么提示吗?

正如我在评论中提到的,问题不在于 IF...ELSE,而是你没有 CATCH。一个TRY...CATCH需要一个TRY一个CATCH;不像 IF...ELSE 只能有 IF.

因此,您可能想要这样的东西:

CREATE PROCEDURE dbo.MyTest AS
BEGIN
    SET NOCOUNT ON;
    BEGIN TRANSACTION MyTransaction;
    BEGIN TRY
        EXEC FOO;
        EXEC BAR;
        EXEC BAZ;
    IF {Your Boolean Expression}
        COMMIT TRANSACTION MyTransaction;
    ELSE
        ROLLBACK TRANSACTION MyTransaction;
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION MyTransaction;
        THROW;
    END CATCH;

END;

您的伪代码缺少一个 catch 块。下面是一个包含错误处理和其他改进的示例。

CREATE PROCEDURE mytest
AS
SET XACT_ABORT ON; --best practice with explict transactions in procs
BEGIN TRY
    BEGIN TRAN;
    EXEC foo;
    EXEC bar;
    EXEC baz;
    IF (<your-validation-succeeded-condition-here>)
        COMMIT;
    ELSE
        ROLLBACK;
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK;
    THROW;
END CATCH;