Использование try / catch для обновления

Поскольку я новичок, я пытаюсь выйти из системы с любыми ошибками, которые могут возникнуть в хранимых процедурах, которые я пишу. Я понимаю Try / Catch в SQL 2005 и 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, которое вызвало проблему.

Спасибо за ваше время.

10.12.2008 19:11:30
2 ОТВЕТА
РЕШЕНИЕ

Блок 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). Однако, если двигаться дальше, если у вас возникнут проблемы с фактическими данными, я бы посоветовал вам взглянуть на добавление внешних ключей и других ограничений для защиты логической целостности вашей базы данных. В идеале, как минимум, вы не можете поместить данные в базу данных, что нарушит ваши хранимые процедуры.

РЕДАКТИРОВАТЬ

Ссылаясь на последние изменения, если вы поместите ОБНОВЛЕНИЕ в хранимую процедуру и поймаете ошибку, затем замените серию обновлений вызовами этой процедуры, остальные обновления будут продолжены, и вы сможете вернуть / отследить / зарегистрировать ошибку в блок захвата SP, как вы хотели.

2
10.12.2008 23:43:25
Спасибо Пол, я думаю, что я сделаю это. Мне трудно описать проблему в первый раз, еще раз спасибо за проверку.
Bob Cummings 10.12.2008 21:39:13

Альтернатива: как насчет использования транзакций и @@ 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
-1
10.12.2008 19:46:48
@@ Идентичность - почти всегда плохой выбор для вставок (это даст неправильное значение, если вы поместите триггер на таблицу, которая вставляет в другую таблицу с идентификатором). И вообще не может использоваться для обновления записи, поскольку она показывает только последнее вставленное значение идентификатора, а не последнее обновленное значение.
HLGEM 10.12.2008 21:13:43