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;
我会问一个基本的问题,如果某些条件得到验证,我会使用本机事务来回滚一堆 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;