Getting a Table Column value in Catch section while using Output clause for Update Statement

Salil Singh 60 Reputation points
2025-05-08T18:13:11.07+00:00

Hi Team,

I am working on a SQL Server Stored Procedure which uses Output clause for Update Statement. Table getting updated is having a column name as ID. I need to put Try Catch in this SP and make sure that row which has errored, I am able to get the field of ID column of that row in Catch section. As the update is happening as per Output clause for Update Statement so not sure on getting ID values of individual rows in Catch section of the SP.

Requesting to please let me know a way through which if error comes while using the Output clause with Update Statement in above SP, how to get the value of ID of row that errored out in Catch section. I am working on SQL Server 2017 version.

Please let me know if more details are required.

Thanks,

Salil

SQL Server Transact-SQL
SQL Server Transact-SQL
SQL Server: A family of Microsoft relational database management and analysis systems for e-commerce, line-of-business, and data warehousing solutions.Transact-SQL: A Microsoft extension to the ANSI SQL language that includes procedural programming, local variables, and various support functions.
181 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Erland Sommarskog 120.4K Reputation points MVP Moderator
    2025-05-08T20:39:21.92+00:00

    It would have helped to see some example code, preferably with sample data. That could have helped to clarify what you are looking for.

    But if the question is "I'm updating a thousand rows in a single UPDATE statement and I get an error. How do I determine which row(s) that caused the error?", the answer is that this information is not available in the general case. Sometimes it can be deduced from the error message, but far from always.

    0 comments No comments

  2. Naveen Kumar M 175 Reputation points
    2025-05-09T07:45:50.9933333+00:00

    In SQL Server, when using the OUTPUT clause with an UPDATE statement inside a TRY...CATCH block, capturing the ID of a specific row that causes an error is not straightforward, because if the error occurs during the statement execution, the entire update operation fails — and SQL Server does not commit any changes, nor does it populate the OUTPUT clause.

    To track the ID of a row that causes an error during the update, especially when updating multiple rows, you can approach this in a two-step manner:

    Approach: Update in a Cursor or Loop with TRY-CATCH Around Each Row

    This method processes each row individually so that any error can be caught along with the ID.

    Step-by-step solution:

    CREATE PROCEDURE dbo.UpdateWithErrorTracking
    AS
    BEGIN
        SET NOCOUNT ON;
        DECLARE @ID INT;
        DECLARE @ErrorMessage NVARCHAR(4000);
        DECLARE @ErrorNumber INT;
        DECLARE @ErrorSeverity INT;
        DECLARE @ErrorState INT;
        DECLARE @ErrorLine INT;
        DECLARE @ErrorProcedure NVARCHAR(128);
        -- Temp table to hold IDs of rows to update
        DECLARE @IDsToUpdate TABLE (ID INT);
        -- Fill with IDs to process
        INSERT INTO @IDsToUpdate (ID)
        SELECT ID FROM YourTable WHERE <YourConditions>;
        DECLARE cur CURSOR LOCAL FAST_FORWARD FOR
        SELECT ID FROM @IDsToUpdate;
        OPEN cur;
        FETCH NEXT FROM cur INTO @ID;
        WHILE @@FETCH_STATUS = 0
        BEGIN
            BEGIN TRY
                UPDATE YourTable
                SET Col1 = 'NewValue'
                OUTPUT inserted.ID, inserted.Col1
                WHERE ID = @ID;
            END TRY
            BEGIN CATCH
                -- Capture error info
                SELECT 
                    @ErrorMessage = ERROR_MESSAGE(),
                    @ErrorNumber = ERROR_NUMBER(),
                    @ErrorSeverity = ERROR_SEVERITY(),
                    @ErrorState = ERROR_STATE(),
                    @ErrorLine = ERROR_LINE(),
                    @ErrorProcedure = ERROR_PROCEDURE();
                -- Log or raise the error with the ID that failed
                RAISERROR('Error updating ID = %d: %s', 16, 1, @ID, @ErrorMessage);
                -- Optionally insert into error log table
                -- INSERT INTO ErrorLog (ID, ErrorMessage, ...)
                -- VALUES (@ID, @ErrorMessage, ...);
            END CATCH;
            FETCH NEXT FROM cur INTO @ID;
        END
        CLOSE cur;
        DEALLOCATE cur;
    END;
    

    Key Notes:

    This method ensures fine-grained error handling per row.

    You sacrifice some performance (because of row-by-row operation), but gain error traceability.

    If performance is critical and the error frequency is low, you could try the bulk update first, and fall back to this method only in the CATCH.

    0 comments No comments

Your answer