Most likely you have a statement in between the error-causing statement and the IF
check. Simplifying the error handling logic here (since it is an extremely vast topic) and ignoring batch-aborting and connection-terminating errors...
This yields the error message and 'Uh oh'
:
SELECT 1/0;
PRINT 'Uh oh';
IF @@ERROR <> 0
BEGIN
PRINT 'Error.';
END
Since @@ERROR
gets reset after every statement, it is no longer non-zero, and the IF
block does not get entered. While the following works as expected, because we are checking @@ERROR
immediately after the trouble statement:
SELECT 1/0;
IF @@ERROR <> 0
BEGIN
PRINT 'Error.';
END
If you do have stuff you need to do in between, you can store the value in a variable:
DECLARE @err INT;
SELECT 1/0;
SELECT @err = @@ERROR;
PRINT 'Uh oh';
IF @err <> 0
BEGIN
PRINT 'Error.';
END
This will execute both PRINT
commands.
EDIT
Since you now added your code, I can give further insight into why this isn't working in your case. Invalid object is a severity 16 error:
Msg 208, Level 16, State 1, Procedure procx, Line 110
Invalid object name 'test'.
Now, according to the documentation, severity 16 does not abort the batch (only 19 and above), but that doesn't mean this is always true. For example, see this blog post which explains that in some cases sev16 can abort the batch. I don't have a 2000 instance anywhere around to test this for certain or to investigate workarounds, other than (a) not creating stored procedures that reference objects that don't exist or (b) upgrading to a modern version of SQL Server that has put a little more thought into error handling).