Quando BACKUP DATABASEgenera un errore, ne genera effettivamente due. Sfortunatamente TRY/CATCHnon è in grado di catturare il primo errore; cattura solo il secondo errore.
Ho il sospetto che la tua migliore scommessa per catturare il vero motivo dietro un backup fallito sia automatizzare i tuoi backup tramite SQLCMD (con -ol'invio di output a un file), SSIS, C #, PowerShell ecc. Tutto ciò ti darà un controllo molto maggiore sulla cattura di tutti degli errori.
La risposta SO nel commento suggerisce l'uso DBCC OUTPUTBUFFER- mentre è possibile, questo non sembra affatto un gioco da ragazzi. Sentiti libero di divertirti con questa procedura dal sito di Erland Sommarskog , ma questo sembra non funzionare bene in combinazione con TRY/CATCH.
L'unico modo in cui mi è sembrato di riuscire a catturare il messaggio di errore spGET_LastErrorMessageè se l'errore reale viene generato. Se lo avvolgi in un TRY/CATCHerrore viene ingoiato e la procedura memorizzata non fa nulla:
BEGIN TRY
EXEC sp_executesql N'backup that fails...';
END TRY
BEGIN CATCH
EXEC dbo.spGet_LastErrorMessage;
END CATCH
In SQL Server <2012 non è possibile aumentare nuovamente l'errore dall'utente, ma è possibile in SQL Server 2012 e versioni successive. Quindi queste due varianti funzionano:
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;
O nel 2012 e oltre, questo funziona, ma in gran parte sconfigge lo scopo TRY/CATCH, poiché l'errore originale viene ancora generato:
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;
In entrambi questi casi, l'errore viene comunque generato al client, ovviamente. Quindi, se stai usando TRY/CATCHper evitarlo, a meno che non ci sia qualche scappatoia a cui non sto pensando, temo che dovrai fare una scelta ... o dare all'utente l'errore ed essere in grado di acquisire dettagli su esso o sopprime sia l'errore sia il motivo reale.