【问题标题】:Using try/catch for update使用 try/catch 进行更新
【发布时间】:2008-12-10 19:11:30
【问题描述】:

因为我是新手,所以我正在尝试注销我编写的存储过程可能出现的任何错误。我了解 SQL 2005 中的 Try/Catch 以及 error_procedure()、ERROR_MESSAGE() 和其他内置函数。我不知道该怎么做是捕获导致更新错误的记录。

我可能会使用游标并一次循环并更新一行。然后在循环中设置一个值并报告该值。但这似乎违背了使用 SQL 的目的。

任何关于在哪里研究这个问题的想法或指针都非常感谢。我不完全理解 RowNumber() 我可以以某种方式使用它吗?有点像抓住稻草了。

干杯和感谢

鲍勃

我使用的是 SQL 2005。

编辑

我真的不想在大多数情况下使用交易,因为它只是用于报告目的。所以我正在做的一个例子是:

/******************************************************************************
   Now get update the table with the current worker.  That depends on the
   current status of the loan.
******************************************************************************/

UPDATE #table SET currWorker = tblUser.UserLogonName
      FROM tblUser
            JOIN tblLoanInvolvement ON tblLoanInvolvement.invlUnderwriterDeptID = tblUser.userID 
            WHERE tblLoanInvolvement.LOANid = #table.loanid
            AND #table.currstatus in('R_UW_Approved','R_Submitted to Underwriting')


  UPDATE #table SET currWorker = tblUser.UserLogonName
  FROM tblUser
        JOIN tblLoanInvolvement ON tblLoanInvolvement.invlProcessorID  = tblUser.userID 
        WHERE tblLoanInvolvement.LOANid = #table.loanid
        AND #table.currstatus in('R_UW Approved With Conditions','R_Loan Resubmitted','R_UW_Suspended','R_Submitted to Processing')

  UPDATE #table SET currWorker = tblUser.UserLogonName
  FROM tblUser
        JOIN tblLoanInvolvement ON tblLoanInvolvement.invlCloserID = tblUser.userID 
        WHERE tblLoanInvolvement.LOANid = #table.loanid
        AND #table.currstatus in('R_Docs Out','R_Ready to Close','R_Scheduled to Close and Fund','Scheduled To Close')

因此,如果某一行没有正确更新,我不想丢失整个内容。但是知道导致问题的#table.loanid 的值会非常方便。

感谢您的宝贵时间。

【问题讨论】:

    标签: sql sql-server sql-server-2005


    【解决方案1】:

    像这样的 try/catch 块...

    BEGIN TRY
        -- Your Code Goes Here --
    END TRY
    BEGIN CATCH
        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
    END CATCH
    

    ...将帮助您在 SQL代码 中找到问题。如果这是在存储过程中,您还可以返回参数(即,将 SELECT @RecordID AS [RecordID] 添加到 catch 块中的该列表)。但是,如果您在实际数据方面遇到问题,我鼓励您考虑添加外键和其他约束以保护数据库的逻辑完整性。理想情况下,您至少不能将数据放入数据库,这会破坏您的存储过程。

    编辑

    参考您最近的编辑,如果您将 UPDATE 放在存储过程中并捕获错误,然后将更新系列替换为对该过程的调用,其余更新将继续,您可以返回/跟踪/记录SP 的 catch 块中的错误,但您希望如此。

    【讨论】:

    • 谢谢保罗,我想我会的。我第一次很难描述这个问题,再次感谢您回来查看。
    【解决方案2】:

    替代方案:使用事务和@@IDENTITY 怎么样?

    DECLARE @problemClientID INT
    BEGIN TRANSACTION
    
        UPDATE ... --etc
    
        IF @@ERROR <> 0
        BEGIN
            ROLLBACK TRANSACTION
            SET @problemClientID = @@IDENTITY
            PRINT N'There was a problem...' --etc
        END
        ELSE
        BEGIN
            -- transaction was a success, do more stuff?
        END
    COMMIT TRANSACTION
    

    【讨论】:

    • @@Identity 对于插入几乎总是一个不好的选择(如果您在表上放置一个触发器,该表将插入到具有标识的不同表中,它将给出错误的值)。并且根本不能用于更新记录,因为它只显示最后插入的标识值而不是最后更新的值。
    猜你喜欢
    • 2011-11-02
    • 2021-11-09
    • 2015-10-19
    • 1970-01-01
    • 2011-10-06
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多