cro*_*sek 10 sql-server backup error-handling
在使用 try catch 和动态 sql 的存储过程中发出备份命令时,与直接运行备份命令相比,错误消息非常普遍。
在 SP 中尝试/捕获:
begin try
execute sp_executesql @sql; -- a backup command
end try
begin catch
print ERROR_MESSAGE(); -- save to log, etc.
end catch
Run Code Online (Sandbox Code Playgroud)
结果是
50000:usp_Backup:117: BACKUP DATABASE 异常终止。
whearea 发出原始命令:
backup DATABASE someDb to disk...
Run Code Online (Sandbox Code Playgroud)
结果更好的细节:
查找错误 - SQL Server 数据库错误:文件“H:\FolderName\Filename.bak:”112(磁盘空间不足。)发生不可恢复的 I/O 错误。
有没有办法将这些细节捕获到存储过程中的变量中(记录,传回调用者,重试逻辑)?似乎细节正在通过消息通道传递,但我希望它们在 SP 中可用。
Aar*_*and 13
当BACKUP DATABASE
产生一个错误时,它实际上产生了两个。不幸的TRY/CATCH
是无法捕获第一个错误;它只捕获第二个错误。
我怀疑捕获失败备份背后真正原因的最佳选择是通过SQLCMD(-o
将输出发送到文件)、SSIS、C#、PowerShell 等自动备份。所有这些都将使您更好地控制捕获所有的错误。
评论中的 SO 答案建议使用DBCC OUTPUTBUFFER
- 虽然有可能,但这似乎根本不是儿戏。随意从 Erland Sommarskog 的网站上享受这个过程的乐趣,但这似乎仍然不能很好地与TRY/CATCH
.
我似乎能够捕获错误消息的唯一方法spGET_LastErrorMessage
是是否确实抛出了实际错误。如果你把它包装在一个TRY/CATCH
错误被吞下并且存储过程什么都不做:
BEGIN TRY
EXEC sp_executesql N'backup that fails...';
END TRY
BEGIN CATCH
EXEC dbo.spGet_LastErrorMessage;
END CATCH
Run Code Online (Sandbox Code Playgroud)
在 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;
Run Code Online (Sandbox Code Playgroud)
或者在 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;
Run Code Online (Sandbox Code Playgroud)
当然,在这两种情况下,错误仍然会被抛出给客户端。因此,如果您要TRY/CATCH
避免这种情况,除非有一些我没有想到的漏洞,否则恐怕您将不得不做出选择……要么向用户提供错误并能够捕获有关的详细信息它,或者同时抑制错误和实际原因。
归档时间: |
|
查看次数: |
19953 次 |
最近记录: |