Va sottolineato che, anche se tecnicamente fosse possibile alternare tra THROW
e RAISERROR
, (molto probabilmente) non si vorrebbe effettivamente farlo. Perché? Perché l'abilità molto nobile del senza parametri THROW
di respingere l'errore usando lo stesso numero di messaggio (cioè Msg 8134
invece di Msg X
dove X
> = 50000) non è l'unica differenza tra loro: THROW
sta interrompendo il batch mentre RAISERROR
non lo è. Questa può essere un'importante differenza comportamentale, come dimostrato di seguito.
Configurazione di prova
--DROP PROC ##Throw;
--DROP PROC ##RaisError;
GO
CREATE PROCEDURE ##Throw
AS
SET NOCOUNT ON;
BEGIN TRY
SELECT 1/0 AS [DivideByZero];
END TRY
BEGIN CATCH
THROW;
END CATCH;
SELECT 1 AS [AA];
GO
CREATE PROCEDURE ##RaisError
AS
SET NOCOUNT ON;
BEGIN TRY
SELECT 1/0 AS [DivideByZero];
END TRY
BEGIN CATCH
RAISERROR('test, yo!', 16, 1);
-- RETURN; -- typically at end of CATCH block when using RAISERROR
END CATCH;
SELECT 2 AS [BB];
GO
Test 1
EXEC ##Throw;
SELECT 3 AS [CC];
Ritorna:
"Results" Tab:
DivideByZero
{empty result set}
"Messages" Tab:
Msg 8134, Level 16, State 1, Procedure ##Throw, Line 38
Divide by zero error encountered.
Test 2
EXEC ##RaisError;
SELECT 4 AS [DD];
Ritorna:
"Results" Tab:
DivideByZero
{empty result set}
BB
2
DD
4
"Messages" Tab:
Msg 50000, Level 16, State 1, Procedure ##RaisError, Line 45
test, yo!
Ad essere onesti, è possibile mascherare questa differenza procedendo come segue:
- Avvolgi sempre tutte le chiamate al codice usando
THROW
all'interno di un TRY...CATCH
costrutto (illustrato di seguito)
- Non inserire mai il codice dopo il
THROW
(bene, tranne per END CATCH;
)
Test 3
BEGIN TRY
EXEC ##Throw;
SELECT 5 AS [EE];
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS [ErrorNumber], ERROR_MESSAGE() AS [ErrorMessage];
END CATCH;
SELECT 6 AS [FF];
GO
Ritorna:
"Results" Tab:
DivideByZero
{empty result set}
ErrorNumber ErrorMessage
8134 Divide by zero error encountered.
FF
6
Test 4
BEGIN TRY
EXEC ##RaisError;
SELECT 7 AS [GG];
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS [ErrorNumber], ERROR_MESSAGE() AS [ErrorMessage];
END CATCH;
SELECT 8 AS [HH];
GO
Ritorna:
"Results" Tab:
DivideByZero
{empty result set}
ErrorNumber ErrorMessage
50000 test, yo!
HH
8