4

我可以在事务中运行动态 sql 并使用 EXEC 回滚:

exec('SELECT * FROM TableA; SELECT * FROM TableB;');

将其放入事务中并在 exec 语句后使用 @@error 进行回滚。

例如。代码

BEGIN TRANSACTION

   exec('SELECT * FROM TableA; SELECT * FROM TableB;');

   IF @@ERROR != 0
     BEGIN
       ROLLBACK TRANSACTION
       RETURN
     END
   ELSE
     COMMIT TRANSACTION

如果有 n 条动态 sql 语句并且在 n/2 中发生错误,将回滚前 1 到 ((n/2) - 1) 条语句


关于第一个答案的问题

@@Error 最有可能不会拾取错误这意味着它可能不会拾取错误,这意味着事务可能会提交?这违背了目的

SQL Server 2005+ 中的 TRY/CATCH 是的,我正在使用 SQL Server 2005,但之前没有使用过 Try Catch

BEGIN TRANSACTION 
   BEGIN TRY 
      exec('SELECT * FROM TableA; SELECT * FROM TableB;'); 
      COMMIT TRANSACTION 
   END TRY 
   BEGIN CATCH 
      ROLLBACK TRANSACTION 
   END CATCH 

或者我在网上看了一些更多的例子

BEGIN TRY --Start the Try Block..
 BEGIN TRANSACTION -- Start the transaction..
  exec('SELECT * FROM TableA; SELECT * FROM TableB;');
 COMMIT TRAN -- Transaction Success!
END TRY
BEGIN CATCH
  IF @@TRANCOUNT > 0
      ROLLBACK TRAN --RollBack in case of Error
  RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1)
END CATCH
4

2 回答 2

7

是的。TXN 属于当前会话/连接,动态 SQL 使用相同的上下文。

但是,@@ERROR 很可能不会发现错误:必须在有问题的语句之后立即检查状态。我会使用 TRY/CATCH,假设 SQL Server 2005+

编辑:TRY/CATCH 应该可以正常工作。

于 2009-12-07T07:11:41.310 回答
0

不要相信我们所说的 try catch 会起作用,自己测试一下。由于这是动态 sql,最简单的做法是使第一条语句正确(当然它需要 bean 更新、插入或删除,或者不需要事务),然后在第二条语句中故意犯语法错误。然后测试第一个语句中的更新插入或删除是否通过。

我还想指出,动态 sql 作为规则是一种不好的做法。这真的需要动态吗?

于 2009-12-07T14:34:11.827 回答