Reputation: 193
I'm using SQL Server in a C# application, and I'm using batch statements. The problem I'm having is in the case where the statement fails, for whatever reason, I need to know which statement failed and return it.
I've managed to do this my putting a try catch
around the SQL statement (so it won't quit if it fails) then the C# cmd.ExecuteQuery
returns the number of rows affected.
The problem I'm having now is that if the failure occurs because of a trigger, the trigger is outside of the try catch
of the original batch and thus won't be caught, but it will instead be caught by the C# application. At this point, the state of the batch is lost in limbo and the whole thing fails.
I need some way of knowing which statement (or the number of rows affected so far, or the index in the batch) triggered the trigger that caused the exception. Whether there's something I can do in SQL or C#, I'm open to whatever.
Thanks.
Upvotes: 0
Views: 1404
Reputation: 239664
This isn't an answer but it's far too big for a comment and it need formatting.
say I have a statement like BEGIN TRY INSERT INTO JAZZHANDS VALUES (2) END TRY BEGIN CATCH END CATCH. If the table JAZZHANDS has a trigger that inserts whatever in some other table, if that trigger fails, it won't cycle back and be caught in the CATCH from the original insert. The transaction just fails altogether
I have no idea why you think that. The following SQL:
create table JazzHands (ID int not null,constraint CK_ID_JH CHECK (ID < 10))
go
create table JazzHands2 (ID int not null,constraint CK_ID_JH2 CHECK (ID < 5))
go
create trigger T_JazzHands on JazzHands after insert
as
insert into JazzHands2(ID)
select ID from inserted
go
--1
begin try
insert into JazzHands (ID) values (11)
PRINT 'No error 1'
end try
begin catch
Print 'error 1'
end catch
go
--2
begin try
insert into JazzHands (ID) values (6)
PRINT 'No error 2'
end try
begin catch
Print 'error 2'
end catch
go
--3
begin try
insert into JazzHands (ID) values (1)
PRINT 'No error 3'
end try
begin catch
Print 'error 3'
end catch
go
Produces:
(0 row(s) affected)
error 1
(0 row(s) affected)
(0 row(s) affected)
error 2
(1 row(s) affected)
(1 row(s) affected)
No error 3
And both tables contain a single row. That, is, contrary to your assertion, when either something within the table itself prevents the insert from succeeding, or something within the trigger on the table prevents the insert from succeeding, exactly the same error handling occurs, and it's generally indistinguishable.
If you do have an actual example where the failure of a trigger produces different behaviour than failure directly on the table, please edit such an example into your question.
Upvotes: 1
Reputation: 10098
What you're looking for is the last statement, right? You can get this information from inside the trigger by calling DBCC INPUTBUFFER
.
See also if this could help:
SELECT session_id, TEXT
FROM sys.dm_exec_connections
CROSS APPLY sys.dm_exec_sql_text(most_recent_sql_handle) AS ST
Upvotes: 0