【问题标题】:Can I rollback Dynamic SQL in SQL Server / TSQL我可以在 SQL Server/TSQL 中回滚动态 SQL
【发布时间】:2009-12-07 07:06:00
【问题描述】:

能否在事务中运行动态 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

【问题讨论】:

    标签: sql tsql error-handling transactions dynamic-sql


    【解决方案1】:

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

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

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

    【讨论】:

    • 已在您回答后扩展了问题。关于TRY/Catch
    【解决方案2】:

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

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

    【讨论】:

    • 我需要从应用程序本身运行 sql 语句。即用户可以进入 asp.net 应用程序,获取一个框并可以从那里运行 sql 语句
    • @soldieraman:哇。您希望知道应用程序的这个“功能”具有大量的安全隐患吗?我只能希望您在针对数据库运行之前至少逃脱或以某种方式清理用户输入?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多