Condividi tramite


Recupero di informazioni sugli errori in Transact-SQL

In Transact-SQL è possibile ottenere le informazioni sugli errori in due modi:

  • Nell'ambito del blocco CATCH di un costrutto TRY…CATCH è possibile utilizzare le funzioni di sistema seguenti:

    • ERROR_LINE() restituisce il numero di riga in cui si è verificato l'errore.

    • ERROR_MESSAGE() restituisce il testo del messaggio che verrebbe inviato all'applicazione. Il testo include i valori specificati per eventuali parametri sostituibili, ad esempio lunghezze, nomi di oggetti o orari.

    • ERROR_NUMBER() restituisce il numero di errore.

    • ERROR_PROCEDURE() restituisce il nome della stored procedure o del trigger in cui si è verificato l'errore. Questa funzione restituisce NULL se l'errore non si è verificato in una stored procedure o in un trigger.

    • ERROR_SEVERITY() restituisce la gravità.

    • ERROR_STATE() restituisce lo stato.

  • Subito dopo avere eseguito un'istruzione Transact-SQL, è possibile verificare la presenza di errori e recuperare il numero di errore utilizzando la funzione @@ERROR.

Utilizzo di ERROR_LINE, ERROR_MESSAGE, ERROR_NUMBER, ERROR_PROCEDURE, ERROR_SEVERITY ed ERROR_STATE

Le funzioni ERROR_LINE, ERROR_MESSAGE, ERROR_NUMBER, ERROR_PROCEDURE, ERROR_SEVERITY ed ERROR_STATE restituiscono le informazioni sull'errore solo quando vengono utilizzate nell'ambito del blocco CATCH di un costrutto TRY…CATCH. All'esterno dell'ambito di un blocco CATCH restituiscono un valore NULL. Queste funzioni restituiscono le informazioni sull'errore a causa del quale il blocco CATCH è stato richiamato. Tali funzioni restituiscono le stesse informazioni sull'errore indipendentemente dalla posizione in cui vengono eseguite nell'ambito di un blocco CATCH, anche se viene fatto riferimento a esse più volte. Le funzioni offrono alle istruzioni Transact-SQL gli stessi dati restituiti all'applicazione.

In blocchi CATCH nidificati le funzioni ERROR_LINE, ERROR_MESSAGE, ERROR_NUMBER, ERROR_PROCEDURE, ERROR_SEVERITY ed ERROR_STATE restituiscono le informazioni sull'errore relativamente al blocco CATCH in cui viene fatto loro riferimento. Ad esempio, il blocco CATCH di un costrutto esterno TRY...CATCH potrebbe includere un costrutto TRY...CATCH nidificato. Nel blocco CATCH nidificato queste funzioni restituiscono le informazioni sull'errore che ha richiamato il blocco CATCH interno. Le stesse funzioni nel blocco CATCH esterno restituirebbero informazioni sull'errore che ha richiamato tale blocco CATCH.

Nell'esempio seguente viene illustrato che quando si fa riferimento a ERROR_MESSAGE nel blocco CATCH esterno, la funzione restituisce il testo del messaggio generato nel blocco TRY esterno. Quando si fa riferimento a ERROR_MESSAGE nel blocco CATCH interno, la funzione restituisce il testo generato nel blocco TRY interno. Nell'esempio viene inoltre illustrato che nel blocco CATCH esterno ERROR_MESSAGE restituisce sempre il messaggio generato nel blocco TRY, anche quando è stato eseguito il costrutto TRY...CATCH interno.

IF EXISTS (SELECT message_id FROM sys.messages
    WHERE message_id = 50010)
        EXECUTE sp_dropmessage 50010;
GO
EXECUTE sp_addmessage @msgnum = 50010,
    @severity = 16, 
    @msgtext = N'Message text is from the %s TRY block.';
GO
BEGIN TRY -- Outer TRY block.
    -- Raise an error in the outer TRY block.
    RAISERROR (50010, -- Message id.
        16, -- Severity,
        1, -- State,
        N'outer'); -- Indicate TRY block.
END TRY -- Outer TRY block.
BEGIN CATCH -- Outer CATCH block.
    -- Print the error message recieved for this
    -- CATCH block.
    PRINT N'OUTER CATCH1: ' + ERROR_MESSAGE();
    BEGIN TRY -- Inner TRY block.
        -- Start a nested TRY...CATCH and generate
        -- a new error.
        RAISERROR (50010, -- Message id.
            16, -- Severity,
            2, -- State,
            N'inner'); -- Indicate TRY block.
    END TRY -- Inner TRY block.
    BEGIN CATCH -- Inner CATCH block.
        -- Print the error message recieved for this
        -- CATCH block.
        PRINT N'INNER CATCH: ' + ERROR_MESSAGE();
    END CATCH; -- Inner CATCH block.
    -- Show that ERROR_MESSAGE in the outer CATCH
    -- block still returns the message from the
    -- error generated in the outer TRY block.
    PRINT N'OUTER CATCH2: ' + ERROR_MESSAGE();
END CATCH; -- Outer CATCH block.
GO

Recupero di informazioni tramite @@ERROR

La funzione @@ERROR può inoltre essere utilizzata per acquisire il numero di un errore generato dall'istruzione Transact-SQL precedente. @@ERROR restituisce le informazioni sull'errore solo immediatamente dopo l'istruzione Transact-SQL che genera l'errore.

  • Se l'istruzione che ha generato l'errore si trova in un blocco TRY, il valore di @@ERROR deve essere verificato e recuperato nella prima istruzione nel blocco CATCH associato.

  • Se l'istruzione che ha generato l'errore non si trova in un blocco TRY, il valore di @@ERROR deve essere verificato e recuperato nell'istruzione immediatamente successiva a quella che ha generato l'errore.

All'esterno dell'ambito di un blocco CATCH il numero di errore in @@ERROR è l'unica informazione disponibile per un errore nel codice Transact-SQL. Se per l'errore è stato utilizzato un messaggio di errore definito in sys.messages, è possibile recuperare la gravità e il testo del messaggio di errore definiti da sys.messages, come illustrato nell'esempio seguente.

IF EXISTS (SELECT message_id FROM sys.messages
    WHERE message_id = 50010)
        EXECUTE sp_dropmessage 50010;
GO
-- Define a message with text that accepts
-- a substitution string.
EXECUTE sp_addmessage @msgnum = 50010,
    @severity = 16, 
    @msgtext = N'Substitution string = %s.';
GO
DECLARE @ErrorVariable INT;
-- RAISERROR uses a different severity and
-- supplies a substitution argument.
RAISERROR (50010, -- Message id.
    15, -- Severity,
    1, -- State,
    N'ABC'); -- Substitution Value.
-- Save @@ERROR.
SET @ErrorVariable = @@ERROR;
-- The results of this select illustrate that
-- outside a CATCH block only the original
-- information from sys.messages is available to
-- Transact-SQL statements. The actual message
-- string returned to the application is not
-- available to Transact-SQL statements outside
-- of a CATCH block.
SELECT @ErrorVariable AS ErrorID,
    text
FROM sys.messages
WHERE message_id = @ErrorVariable;
GO