【问题标题】:SQL re-execute stored procedure within try catch blockSQL 在 try catch 块中重新执行存储过程
【发布时间】:2012-02-08 16:11:55
【问题描述】:

我有一个正在执行 MERGE 的存储过程。考虑到流量,似乎两个请求同时调用 INSERT 而不是 UPDATE。由于外键约束,其中一个请求失败。如果我将合并语句放在 try catch 中并尝试重新执行存储过程,我假设这次它将运行 MERGE 的 UPDATE 部分并成功。对此的想法,它被认为是好的/坏的做法吗?

如果这很重要,我正在使用 SQL Server 2008。

提前喝彩

【问题讨论】:

    标签: sql stored-procedures merge try-catch


    【解决方案1】:

    您可以在 try/catch 块中复制它,但更好的解决方案可能是解决并发运行时的锁定问题。在合并语句之前,实现类似这样的规范方法如下:

    BEGIN TRANSACTION;
    
    UPDATE dbo.Table WITH (HOLDLOCK)
    SET Col = @Val
    WHERE Key= @Something;
    
    IF @@ROWCOUNT = 0
      INSERT INTO dbo.TABLE (Key, Col) VALUES (@Key, @Val);
    
    COMMIT TRANSACTION;
    

    因此,对于 MERGE,我建议您执行以下操作:

    MERGE dbo.Table WITH (HOLDLOCK) ...

    我还建议使用 http://www.datamanipulation.net/sqlquerystress/ 测试并发性

    【讨论】:

      【解决方案2】:
      -- Verify that the stored procedure does not already exist.
      
      
      IF OBJECT_ID ( 'usp_GetErrorInfo', 'P' ) IS NOT NULL 
          DROP PROCEDURE usp_GetErrorInfo;
      GO
      
      -- Create procedure to retrieve error information.
      CREATE PROCEDURE usp_GetErrorInfo
      AS
      SELECT
          ERROR_NUMBER() AS ErrorNumber
          ,ERROR_SEVERITY() AS ErrorSeverity
          ,ERROR_STATE() AS ErrorState
          ,ERROR_PROCEDURE() AS ErrorProcedure
          ,ERROR_LINE() AS ErrorLine
          ,ERROR_MESSAGE() AS ErrorMessage;
      GO
      
      BEGIN TRY
          -- Generate divide-by-zero error.
          SELECT 1/0;
      END TRY
      BEGIN CATCH
          -- Execute error retrieval routine.
          EXECUTE usp_GetErrorInfo;
      END CATCH; 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-09
        • 2014-12-13
        • 2010-12-01
        • 1970-01-01
        • 2016-01-28
        • 1970-01-01
        相关资源
        最近更新 更多