Answered by:
The catch does NOT catch

Question
-
begin try
in the above code where NonexistingTable is a non-existing table, the catch block does NOT catch the error. Why? thanks. Andrew
delete from NonexistingTable
end try
begin catch
print 'catch u'
end catch
Interested in BI related technologiesFriday, November 20, 2009 3:55 PM
Answers
-
This is because of deferred name resolution in SQL Server. You can read in more details here:
http://www.sommarskog.se/strict_checks.html#killDNR
One way to catch such errors is in outer procedure that has TRY...CATCH. Using TRY...CATCH at the same level will not work.
Plamen Ratchev- Proposed as answer by Kalman Toth Friday, November 20, 2009 4:24 PM
- Marked as answer by Andrew Goodnight Wednesday, November 25, 2009 3:31 AM
Friday, November 20, 2009 4:12 PM -
Andrew,
outer procedure still can NOT catch
Interested in BI related technologies
You are right. Plain nesting of TRY-CATCH will not do it.
I know of two ways to nest it: stored procedure nesting and dynamic SQL as shown following:
-- TRY-CATCH nesting demo BEGIN TRY -- OUTER TRY-CATCH EXEC ('begin try delete from NonexistingTable end try begin catch print ''catch u'' end catch') END TRY BEGIN CATCH print 'catch u in OUTER TRY-CATCH' END CATCH -- catch u in OUTER TRY-CATCH
Related article: http://www.sqlusa.com/articles2008/trycatch/
Kalman Toth, SQL Server & BI Training, SSAS, SSIS, SSRS; http://www.SQLUSA.com- Marked as answer by Andrew Goodnight Wednesday, November 25, 2009 3:32 AM
- Edited by Kalman Toth Friday, April 6, 2012 9:58 PM
Saturday, November 21, 2009 2:38 PM -
Non existing object raises error of severity 16 and you can catch it in the outer procedure. Here is a proof:
BEGIN TRY EXEC (' BEGIN TRY DELETE FROM NonexistingTable; END TRY BEGIN CATCH PRINT ERROR_MESSAGE(); END CATCH'); END TRY BEGIN CATCH PRINT ERROR_MESSAGE(); END CATCH /* Invalid object name 'NonexistingTable'. */
Plamen Ratchev- Proposed as answer by Naomi N Monday, November 23, 2009 12:58 PM
- Marked as answer by Andrew Goodnight Wednesday, November 25, 2009 3:32 AM
Saturday, November 21, 2009 3:54 PM -
Keep in mind how this is actually working.
When the stored proc sprocDelta is called, it then calls sprocAlpha, which simply TERMINATES at the "DELETE...." line, no other processing in sprocAlpha continues. The error is then caught by the outer stored proc sprocDelta.
- Marked as answer by Andrew Goodnight Wednesday, November 25, 2009 3:33 AM
Monday, November 23, 2009 1:49 PM
All replies
-
begin try delete from NonexistingTable end try begin catch print 'catch u' end catch in the above code where NonexistingTable is a non-existing table, the catch block does NOT catch the error. Why? thanks. Andrew
Interested in BI related technologies- Merged by Jonathan KehayiasMVP Friday, November 20, 2009 4:27 PM Duplicates
Friday, November 20, 2009 3:48 PM -
begin try
delete from foo
end try
begin catch
print 'catch u'
end catch
it gives me invalid object name 'foo' syntax error
Try...CATCH doesn't handle errors with severity 10 and under
BEGIN TRY
-- Raise an error of severity 10. This will not invoke the
-- CATCH block and the message is returned to the client.
RAISERROR ('Informational Message', 10, 1);
-- Generate divide-by-zero error. This will invoke the
-- CATCH block
SELECT 1/0;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() as ErrorState,
ERROR_LINE() as ErrorLine,
ERROR_MESSAGE() as ErrorMessage;
END CATCH;
GO- Proposed as answer by Kalman Toth Friday, November 20, 2009 4:24 PM
Friday, November 20, 2009 3:55 PM -
Chirag is correct, these errors are not caught in the CATCH block, you might want to check if the table exists first, and if it doesn't you can use GOTO and create a block to send you a message or perform another operation
Abdallah, PMP, ITIL, MCTSFriday, November 20, 2009 3:59 PM -
forum members continue here
http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/0450b4d6-05e4-4166-b1fa-c183f51684e7Friday, November 20, 2009 4:02 PM -
This is because of deferred name resolution in SQL Server. You can read in more details here:
http://www.sommarskog.se/strict_checks.html#killDNR
One way to catch such errors is in outer procedure that has TRY...CATCH. Using TRY...CATCH at the same level will not work.
Plamen Ratchev- Proposed as answer by Kalman Toth Friday, November 20, 2009 4:24 PM
- Marked as answer by Andrew Goodnight Wednesday, November 25, 2009 3:31 AM
Friday, November 20, 2009 4:12 PM -
Chirag is correct, these errors are not caught in the CATCH block, you might want to check if the table exists first, and if it doesn't you can use GOTO and create a block to send you a message or perform another operation
Abdallah, PMP, ITIL, MCTS
What to do if I want to catch all the error?
thanks.
Andrew
Interested in BI related technologiesSaturday, November 21, 2009 1:19 PM -
This is because of deferred name resolution in SQL Server. You can read in more details here:
http://www.sommarskog.se/strict_checks.html#killDNR
One way to catch such errors is in outer procedure that has TRY...CATCH. Using TRY...CATCH at the same level will not work.
Plamen Ratchev
Thanks, Plamen
outer procedure still can NOT catch errors raised in inner procedure with severity 10 and under
Interested in BI related technologiesSaturday, November 21, 2009 1:29 PM -
Andrew,
outer procedure still can NOT catch
Interested in BI related technologies
You are right. Plain nesting of TRY-CATCH will not do it.
I know of two ways to nest it: stored procedure nesting and dynamic SQL as shown following:
-- TRY-CATCH nesting demo BEGIN TRY -- OUTER TRY-CATCH EXEC ('begin try delete from NonexistingTable end try begin catch print ''catch u'' end catch') END TRY BEGIN CATCH print 'catch u in OUTER TRY-CATCH' END CATCH -- catch u in OUTER TRY-CATCH
Related article: http://www.sqlusa.com/articles2008/trycatch/
Kalman Toth, SQL Server & BI Training, SSAS, SSIS, SSRS; http://www.SQLUSA.com- Marked as answer by Andrew Goodnight Wednesday, November 25, 2009 3:32 AM
- Edited by Kalman Toth Friday, April 6, 2012 9:58 PM
Saturday, November 21, 2009 2:38 PM -
Here is one way to check if the table exists. If it does do some action, else daise an error
IF EXISTS (SELECT 1 FROM sys.objects WHERE Object_id = object_id(N'SomeTable')) DELETE FROM SomeTable ELSE RAISERROR ('Table doesn''t exist', 10, 1);
Abdallah, PMP, ITIL, MCTSSaturday, November 21, 2009 2:39 PM -
Non existing object raises error of severity 16 and you can catch it in the outer procedure. Here is a proof:
BEGIN TRY EXEC (' BEGIN TRY DELETE FROM NonexistingTable; END TRY BEGIN CATCH PRINT ERROR_MESSAGE(); END CATCH'); END TRY BEGIN CATCH PRINT ERROR_MESSAGE(); END CATCH /* Invalid object name 'NonexistingTable'. */
Plamen Ratchev- Proposed as answer by Naomi N Monday, November 23, 2009 12:58 PM
- Marked as answer by Andrew Goodnight Wednesday, November 25, 2009 3:32 AM
Saturday, November 21, 2009 3:54 PM -
Andrew,
You are right. Plain nesting of TRY-CATCH will not do it.
I know of two ways to nest it: stored procedure nesting and dynamic SQL as shown following:
Kalman Toth, SQL Server & BI Training, SSAS, SSIS, SSRS; http://www.SQLUSA.com
Hi,Kalman
thanks,
and would u please show me an example of stored procedure nesting(which is not plain)
Regards,
AndrewMonday, November 23, 2009 8:14 AM -
Keep in mind how this is actually working.
When the stored proc sprocDelta is called, it then calls sprocAlpha, which simply TERMINATES at the "DELETE...." line, no other processing in sprocAlpha continues. The error is then caught by the outer stored proc sprocDelta.
- Marked as answer by Andrew Goodnight Wednesday, November 25, 2009 3:33 AM
Monday, November 23, 2009 1:49 PM -
Hi,all
Neither dynamic SQL nor procedure nesting can catch error with severity 10 and under.
Interested in BI related technologiesTuesday, November 24, 2009 1:45 AM -
Andrew, I think you should check if the object exists before you do any action just like in the example I gave you.
Abdallah, PMP, ITIL, MCTSTuesday, November 24, 2009 1:50 AM -
Andrew, I think you should check if the object exists before you do any action just like in the example I gave you.
Abdallah, PMP, ITIL, MCTS
Thanks,Abdallah
I do appreciate ur suggestion.
while,I am more interested in the principle of try-catch block.
Andrew
Interested in BI related technologiesTuesday, November 24, 2009 2:07 AM -
Yes, and there is a reason for that. Severity 10 and under is for informational messages and warnings which are not considered errors and as such should not interrupt the execution of the code. Your example with non existing object is not a valid case as it generates error of severity 16 and can be trapped in outer block as I demonstrated.
Plamen RatchevTuesday, November 24, 2009 2:48 AM -
So,
the problem goes to what types of errors can NOT be caught be catch-block in the same level,but CAN BE in outer proc.
thanks.
Andrew
Interested in BI related technologiesTuesday, November 24, 2009 3:50 AM -
This is described in BOL:
http://msdn.microsoft.com/en-us/library/ms175976.aspx
The following types of errors are not handled by a CATCH block when they occur at the same level of execution as the TRY…CATCH construct:
- Compile errors, such as syntax errors, that prevent a batch from running.
- Errors that occur during statement-level recompilation, such as object name resolution errors that occur after compilation because of deferred name resolution.
These errors are returned to the level that ran the batch, stored procedure, or trigger.
Plamen RatchevTuesday, November 24, 2009 4:25 AM -
These errors are returned to the level that ran the batch, stored procedure, or trigger.
Thanks
Andrew
Interested in BI related technologiesTuesday, November 24, 2009 5:00 AM -
Yes, because they are returned to the outer level as indicated.
Plamen RatchevTuesday, November 24, 2009 5:49 AM