Question

I’m executing batch SQL commands in C# using SQLConnection and command. I need to be able to know which statement fails, and I can’t do these one at a time because of performance issues. Is there any way in C# that I can execute a batch SQL statement, and in the case of failure, tell me what statement fails (the index, id, or anything so I can know which one) and THEN continue with the rest of the statements.

Thanks

Was it helpful?

Solution

You didn't mention what database you're using, but if you're using SQL Server 2005 or greater, you can use try/catch for this. Here's an example.

BEGIN TRY
    select 1/0
END TRY
BEGIN CATCH
    SELECT 'statement 1 failed' AS Statement,ERROR_MESSAGE() as ErrorMessage,ERROR_SEVERITY() AS Severity;
END CATCH

BEGIN TRY
    select 1.0/2
END TRY
BEGIN CATCH
    SELECT 'statement 2 failed' AS Statement,ERROR_MESSAGE() as ErrorMessage,ERROR_SEVERITY() AS Severity;
END CATCH

In this case I'm catching the errors and just returning them as a result set, but you could create a temp table/variable at the beginning, insert into that when an error happens, and then select all rows from that table at the end.

EDIT: Here's an example that will throw an error in a trigger:

create table csm (id int)
go
create trigger tr_i_csm on csm for insert as
declare @d int
select @d=sum(id) from inserted
if (@d>=10)
begin
 raiserror('error',@d,0)
end
go

BEGIN TRY
    BEGIN TRAN
    insert into csm values (5)
    COMMIT
END TRY
BEGIN CATCH
    ROLLBACK
    SELECT 'statement 1 failed' AS Statement,ERROR_MESSAGE() as ErrorMessage,ERROR_SEVERITY() AS Severity;
END CATCH

BEGIN TRY
    BEGIN TRAN
    insert into csm values(16)
    COMMIT
END TRY
BEGIN CATCH
    ROLLBACK
    SELECT 'statement 2 failed' AS Statement,ERROR_MESSAGE() as ErrorMessage,ERROR_SEVERITY() AS Severity;
END CATCH

BEGIN TRY
    BEGIN TRAN
    insert into csm values(2)
    COMMIT
END TRY
BEGIN CATCH
    ROLLBACK
    SELECT 'statement 3 failed' AS Statement,ERROR_MESSAGE() as ErrorMessage,ERROR_SEVERITY() AS Severity;
END CATCH

selecT * from csm

OTHER TIPS

One option is to include print statements in your batches following each query. You can then look at the output to find failures. (See here for information on how to read this).

In a prior job, we had a number of nightly stored procedures that ran via Sql Agent, and some other non-database jobs written in C# that ran as Windows Scheduled Tasks. We eventually wrote a c# program to call the stored procedures, instead of Sql Agent, so that we could have all of our scheduling (and logging!) in one place (scheduled tasks). We also had support for executing an Sql file via the program. Receiving Print message output was how we handled logging.

Of course, this implies the ability to modify your batch scripts. It also means writing the sql such that a failed statement won't terminate the whole job.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top