sql-servert-sql

Does the T-SQL Error Severity impact whether a script continues with the next statement?


Given this table

CREATE TABLE [dbo].[Table_2](
    [X] [int] IDENTITY(1,1) NOT NULL,
    [Y] [varchar](30) NULL,
 CONSTRAINT [PK_Table_2] PRIMARY KEY CLUSTERED 
(
    [X] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

When I run the following code against the empty table, the first insert succeeds but the second one will fail because the code is attempting to insert a duplicate value for an identity column.

BEGIN
    
    SET IDENTITY_INSERT Table_2 ON

    PRINT 'Insert 1'

    INSERT INTO Table_2
                (X, Y)
    VALUES      (3, CAST(getdate() AS varchar(30)) )

    PRINT 'Insert 2'

    INSERT INTO Table_2
                (X, Y)
    VALUES      (3, CAST(getdate() AS varchar(30)) )

    PRINT 'Insert 3'

    INSERT INTO Table_2
                (X, Y)
    VALUES      (4, CAST(getdate() AS varchar(30)) )

    SET IDENTITY_INSERT Table_2 OFF    

END 

output:

Insert 1

(1 row(s) affected)
Insert 2

Msg 2627, Level 14, State 1, Line 13
Violation of PRIMARY KEY constraint 'PK_Table_2'. Cannot insert duplicate key in object 'dbo.Table_2'.

Insert 3

(1 row(s) affected)

Instead of the script topping execution at the point where the error is encountered, execution continues with the next insert statement, which succeeds.

I realize that I can use a TRY CATCH block to catch the error when it occurs but my question is this:

I notice that the severity of the error is 14. I assume that an error of sufficient severity level would cause the execution to abort. Is this correct, and what min severity level is needed to cause the script to abort?


Solution

  • You can use SET options to stop execution of a transaction on an error:

    SET XACT_ABORT ON
    

    http://msdn.microsoft.com/en-us/library/ms188792.aspx

    However, you'll need to wrap your code in a transaction to get the all-or-nothing behavior.

    SET XACT_ABORT ON
    BEGIN  TRAN
    
    SET IDENTITY_INSERT Table_2 ON
    
    PRINT 'Insert 1'
    
    INSERT INTO Table_2
                (X, Y)
    VALUES      (3, CAST(getdate() AS varchar(30)) )
    
    PRINT 'Insert 2'
    
    INSERT INTO Table_2
                (X, Y)
    VALUES      (3, CAST(getdate() AS varchar(30)) )
    
    PRINT 'Insert 3'
    
    INSERT INTO Table_2
                (X, Y)
    VALUES      (4, CAST(getdate() AS varchar(30)) )
    
    SET IDENTITY_INSERT Table_2 OFF    
    
    COMMIT
    SET XACT_ABORT OFF