T-SQL Transaction with many (1000+) INSERTS gets disconnected

Is there a limit on the number of INSERT statements you can put inside a transaction? I am getting a transport error and the connection disconnects in the middle of running the statement.

Should I just populate a temp table and then run a single INSERT statement?

Error Message in the middle of a 1000+ insert inside a transaction...

Msg 233, Level 20, State 0, Line 0
A transport-level error has occurred when receiving results from the server. 
(provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.)

I run the script inside SQL Server 2008 R2 10.50.4000.0 against a database on my local Windows 8 machine (Toshiba Satellite S955, x64 8GB RAM, Intel (R) Core(TM) i5-3317U CPU @ 1.70GHz 1.70 GHz)

declare @currentDatabase nvarchar(255);
select @currentDatabase = DB_NAME();

if CHARINDEX('canada', @currentDatabase) = 0
begin
    print 'Please run this script on the Canada server'
    return
end

begin try
begin transaction
SET IDENTITY_INSERT company_name ON
insert into company_name (company_name_id, company_name, display_index, approved_by_administrator, requestor_id, modify_timestamp, active, create_timestamp) values (10000601010001, '6 Day Dental', 5868, 1, NULL, '2013-04-08 00:00:00.000', 1, '2013-04-08 00:00:00.000');
insert into company_name (company_name_id, company_name, display_index, approved_by_administrator, requestor_id, modify_timestamp, active, create_timestamp) values (10000601010002, '7-Eleven', 5869, 1, NULL, '2013-04-08 00:00:00.000', 1, '2013-04-08 00:00:00.000');
insert into company_name (company_name_id, company_name, display_index, approved_by_administrator, requestor_id, modify_timestamp, active, create_timestamp) values (10000601010003, 'AC Properties', 5870, 1, NULL, '2013-04-08 00:00:00.000', 1, '2013-04-08 00:00:00.000');
-- 1287 more INSERT statements...
SET IDENTITY_INSERT company_name OFF

commit
end try
begin catch
    rollback
    declare @Msg nvarchar(max)
    select @Msg=Error_Message();
    raiserror('Error Occured: %s', 20, 101,@Msg) with log
end catch

Answers


Problem

I believe your problem lies in the following line:

raiserror('Error Occured: %s', 20, 101,@Msg) with log

To start, let's take a look at the signature of RAISERROR:

RAISERROR ( { msg_id | msg_str | @local_variable } { ,severity ,state } [ ,argument [ ,...n ] ] ) [ WITH option [ ,...n ] ]

As emphasized, the piece I want to focus on is the severity argument. Within the same MSDN page, you will find the following (regarding the severity argument):

[severity] Is the user-defined severity level associated with this message

Also:

Severity levels from 0 through 18 can be specified by any user. Severity levels from 19 through 25 can only be specified by members of the sysadmin fixed server role or users with ALTER TRACE permissions. For severity levels from 19 through 25, the WITH LOG option is required.

So far, so good. From your code snippet, we can see that an error message with a severity level of 20 is being generated, via RAISERROR. As such, the WITH LOG option is utilized.

However, the MSDN page also notes:

Severity levels from 20 through 25 are considered fatal. If a fatal severity level is encountered, the client connection is terminated after receiving the message, and the error is logged in the error and application logs.

So, in effect, your call to RAISERROR is terminating your connection.

Solution

I assume that your intention for the CATCH block is to "rethrow" the original error that caused the CATCH block to run. If so, take a look at the following (taken from Is there an equivalent in T-SQL to C#'s "throw;" to re-throw exceptions?):

...
BEGIN CATCH
    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    SELECT @ErrorMessage = ERROR_MESSAGE(),
           @ErrorSeverity = ERROR_SEVERITY(),
           @ErrorState = ERROR_STATE();

    -- Use RAISERROR inside the CATCH block to return 
    -- error information about the original error that 
    -- caused execution to jump to the CATCH block.
    RAISERROR (@ErrorMessage, -- Message text.
               @ErrorSeverity, -- Severity.
               @ErrorState -- State.
               );
END CATCH;

This uses ERROR_MESSAGE(), ERROR_SEVERITY(), and ERROR_STATE() to gather information about the error that caused the CATCH block to run. It then uses RAISERROR to generate a new error message with said information.


Need Your Help

Looking for examples of “real” uses of continuations

ruby language-agnostic scheme smalltalk continuations

I'm trying to grasp the concept of continuations and I found several small teaching examples like this one from the Wikipedia article:

Add Items to the ComboBox

c# .net combobox

I have a ComboBox control.