当BACKUP DATABASE
产生错误时,它实际上产生两个。不幸的TRY/CATCH
是无法捕获第一个错误;它仅捕获第二个错误。
我怀疑捕获失败备份背后的真正原因的最佳选择是通过SQLCMD(-o
用于将输出发送到文件),SSIS,C#,PowerShell等自动执行备份。所有这些都将为您提供更好的控制所有捕获功能错误。
评论中的SO答案建议使用DBCC OUTPUTBUFFER
-尽管有可能,但这似乎根本不是儿童游戏。可以在Erland Sommarskog的站点上随意使用此过程,但与结合使用似乎仍然效果不佳TRY/CATCH
。
我似乎能够捕获错误消息的唯一方法spGET_LastErrorMessage
是是否抛出实际错误。如果将其包装在a中TRY/CATCH
,错误将被吞没,并且存储过程将不执行任何操作:
BEGIN TRY
EXEC sp_executesql N'backup that fails...';
END TRY
BEGIN CATCH
EXEC dbo.spGet_LastErrorMessage;
END CATCH
在SQL Server <2012中,您不能自己重新引发该错误,但可以在SQL Server 2012及更高版本中。因此,这两种变体有效:
CREATE PROCEDURE dbo.dothebackup
AS
BEGIN
SET NOCOUNT ON;
EXEC sp_executesql N'backup that fails...';
END
GO
EXEC dbo.dothebackup;
EXEC dbo.spGET_LastErrorMessage;
或在2012年及以后的版本中,此方法有效,但在很大程度上未能达到的目的TRY/CATCH
,因为仍会引发原始错误:
CREATE PROCEDURE dbo.dothebackup2
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
EXEC sp_executesql N'backup that fails...';
END TRY
BEGIN CATCH
THROW;
END CATCH
END
GO
EXEC dbo.dothebackup2;
EXEC dbo.spGET_LastErrorMessage;
当然,在这两种情况下,错误仍然会抛出给客户端。因此,如果您要TRY/CATCH
避免这种情况,除非有我不介意的漏洞,否则恐怕您必须做出选择……要么为用户提供错误信息,要么能够捕获有关以下内容的详细信息:或抑制错误和实际原因。