You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

tSQLt中TRY/CATCH块报错后AssertEqualsTableSchema等断言失效问题

tSQLt TRY/CATCH块后复杂断言报错问题解决方案

根本原因

这个现象是SQL Server的事务机制与tSQLt不同断言的内部实现差异共同导致的,不属于不可解决的底层限制:

  • 当TRY块内触发严重级别的错误时,SQL Server会将当前事务标记为不可提交状态(即XACT_STATE()返回-1),此时事务仅支持全量回滚,禁止任何写入日志、创建/修改对象类的操作,否则会直接抛出你遇到的事务不可提交错误。
  • 你列出的AssertEquals这类简单断言,内部仅做参数值的逻辑比较,不涉及任何写操作,所以在不可提交事务中也可以正常运行。
  • 而AssertEqualsTableSchema、AssertEqualsTable这类复杂断言,内部需要创建临时表、写入tSQLt内部统计日志等写操作,碰到不可提交的事务自然会报错。

解决方案

方案1(推荐,符合tSQLt设计规范)

如果你的测试目的就是验证指定逻辑会抛出异常,不要手动写TRY/CATCH块,直接使用tSQLt内置的tSQLt.ExpectException方法,不会触发事务不可提交的问题,示例用法:

EXEC tSQLt.ExpectException @ExpectedMessage = '转换失败'
-- 执行你预期会抛错的逻辑
DECLARE @IntegerVariable AS INT;
SET @IntegerVariable = 'a string';

方案2(兼容自定义TRY/CATCH场景)

如果确实需要手动实现TRY/CATCH逻辑,在CATCH块结束后、调用复杂断言之前,先重置事务状态即可:

BEGIN CATCH
    PRINT('An error happened.');
END CATCH

-- 新增以下代码重置事务状态
IF XACT_STATE() = -1
BEGIN
    ROLLBACK TRANSACTION;
    BEGIN TRANSACTION;
END

这段代码会将不可提交的事务全量回滚,再新开一个可正常执行写操作的事务,后续所有复杂断言都可以正常运行。

验证效果

把上述重置事务的代码加入你给出的复现代码中,再运行AssertEqualsTableSchema断言,测试会正常返回通过/失败结果,不会再触发事务报错。

内容的提问来源于stack exchange,提问作者pygri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:45:03