现在我们对为什么会发生这种情况有了所有的解释。让我们看看问题的实际解决方案。
首先让我们将上面@d-k-mulligan 提出的语句转化为存储过程。
IF OBJECT_ID('dbo.prcIDontExistINSERT', 'P') IS NOT NULL DROP PROCEDURE dbo.prcIDontExistINSERT
GO
CREATE PROCEDURE dbo.prcIDontExistINSERT
AS
BEGIN TRY
INSERT INTO IDontExist(ProductID)
VALUES(1)
END TRY
BEGIN CATCH
SELECT 'There was an error! ' + ERROR_MESSAGE()
END CATCH
GO
IF OBJECT_ID('dbo.prcIDontExistSELECT', 'P') IS NOT NULL DROP PROCEDURE dbo.prcIDontExistSELECT
GO
CREATE PROCEDURE dbo.prcIDontExistSELECT
AS
BEGIN TRY
SELECT * FROM IDontExist
END TRY
BEGIN CATCH
SELECT 'There was an error! ' + ERROR_MESSAGE()
END CATCH
GO
如果我们运行其中任何一个,我们都会看到相同的错误。
EXEC dbo.prcIDontExistINSERT
EXEC dbo.prcIDontExistSELECT
Msg 208, Level 16, State 1, Procedure prcIDontExistSELECT, Line 4
Invalid object name 'IDontExist'.
现在的解决方案是创建错误处理包装 proc,其唯一目的是从上面的原始 proc 中捕获任何导致对象未找到错误的错误。
IF OBJECT_ID('dbo.prcIDontExistInsert_ERROR_HANDLER', 'P') IS NOT NULL DROP PROCEDURE dbo.prcIDontExistInsert_ERROR_HANDLER
GO
CREATE PROCEDURE dbo.prcIDontExistInsert_ERROR_HANDLER
AS
BEGIN TRY
EXEC dbo.prcIDontExistINSERT
END TRY
BEGIN CATCH
SELECT 'There was an error! ' + ERROR_MESSAGE()
END CATCH
GO
IF OBJECT_ID('dbo.prcIDontExistSELECT_ERROR_HANDLER', 'P') IS NOT NULL DROP PROCEDURE dbo.prcIDontExistSELECT_ERROR_HANDLER
GO
CREATE PROCEDURE dbo.prcIDontExistSELECT_ERROR_HANDLER
AS
BEGIN TRY
EXEC dbo.prcIDontExistSELECT
END TRY
BEGIN CATCH
SELECT 'There was an error! ' + ERROR_MESSAGE()
END CATCH
GO
最后,让我们运行我们的任一错误处理过程并查看我们期望的消息。
EXEC dbo.prcIDontExistInsert_ERROR_HANDLER
EXEC dbo.prcIDontExistSELECT_ERROR_HANDLER
There was an error! Invalid object name 'IDontExist'.
注意:Kalman Toth 在这里完成了所有艰苦的研究工作:
http://www.sqlusa.com/articles2008/trycatch/