About a month ago, I'd written about unhandled errors in .NET procedural code always causing error 6522 to be returned to the (T-SQL) caller (see "Error 6522 and You"). Because the "real" error (the one that caused the .NET code exception) is wrapped in a 6522 error, retrieving the value of @@error will always give you 6522, not the real error. The canonical example is:
public static void Proc1
{
SqlCommand cmd = SqlContext.GetCommand();
// causes error 547 – reference constraint
cmd.CommandText = "delete authors where au_id like '1%'";
SqlContext.GetPipe().Execute(cmd);
}
Called from T-SQL:
execute proc1
select @@error
The error you get is:
Msg 6522, Level 16, State 1, Procedure CauseError, Line 1
A .NET Framework error occurred during execution of user defined routine or aggregate 'CauseError':
System.Data.SqlServer.SqlException: DELETE statement conflicted with REFERENCE constraint 'FK__titleauth__au_id__0AD2A005'. The conflict occurred in database 'pubs', table 'titleauthor', column 'au_id'.
@@error = 6522
This week one of the students in SQL Server 2005 class discovered a neat workaround. Wrap the .NET code in a try-catch block and do nothing in the catch block. Like this:
public static void Proc1
{
try
{
SqlCommand cmd = SqlContext.GetCommand();
// causes error 547 – reference constraint
cmd.CommandText = "delete authors where au_id like '1%'";
SqlContext.GetPipe().Execute(cmd);
}
catch { // dummy catch block }
}
This produces the expected error. And the expected value of @@error:
Msg 547, Level 16, State 0, Line 1
DELETE statement conflicted with REFERENCE constraint 'FK__titleauth__au_id__0AD2A005'. The conflict occurred in database 'pubs', table 'titleauthor', column 'au_id'.
@@error = 547
I'll have to try this in some other example exceptions, but it seems to do the trick in this one. Thanks to Bertil Syamken for the suggestion.