elenco di errori di interruzione batch nel server SQL


9

In SQL Server, se XACT_ABORT è disattivato, alcuni errori interromperanno l'istruzione corrente (ad esempio fornendo il numero errato di parametri a una procedura memorizzata che accetta alcuni parametri) e alcuni errori interromperanno l'intero batch (ad esempio fornendo parametri a un archivio procedura che non accetta parametri). [Riferimento]: http://www.sommarskog.se/error-handling-I.html#scope-abortion .

Quello che vorrei sapere è se esiste un elenco definitivo di quali errori interrompono il batch e quali terminano le dichiarazioni.

Risposte:


6

Credo che ci siano alcune eccezioni, ma da Gravità errori motore di database (MSDN) :

I messaggi di errore con un livello di gravità di 19 o superiore interrompono l'esecuzione del batch corrente.

Gli errori che interrompono la connessione al database, in genere con gravità compresa tra 20 e 25, non vengono gestiti dal blocco CATCH poiché l'esecuzione viene interrotta al termine della connessione.

Quindi sembra che potresti ottenere un elenco definitivo dalla seguente query (ovviamente questo non ti permetterà di filtrare quali possono essere causati dall'utente T-SQL):

SELECT message_id, severity, [text]
FROM sys.messages
WHERE language_id = 1033 
AND severity >= 19
ORDER BY severity, message_id;

In SQL Server 2012, questo produce 210 righe.

In SQL Server 2016, questo produce 256 righe.

A proposito, non credo che i due scenari che descrivi nella tua domanda funzionino come pensi, almeno non nelle versioni moderne di SQL Server. L'ho provato sia nel 2012 che nel 2016 (credo che l'articolo di Erland descriva il comportamento di SQL Server 2000, che non ricordo se fosse diverso, ma non molto rilevante oggi, anche se così).

USE tempdb;
GO

CREATE PROCEDURE dbo.pA -- no parameters
AS PRINT 1
GO
CREATE PROCEDURE dbo.pB -- two parameters
@x INT, @y INT
AS PRINT 1
GO

SET XACT_ABORT OFF;
GO

EXEC dbo.pA @foo = 1; 
PRINT '### Calling procedure that doesn''t take parameters with a parameter';
GO

EXEC dbo.pB; 
PRINT '### Calling procedure that takes 2 parameters with no parameters';
GO

EXEC dbo.pB @x = 1; 
PRINT '### Calling procedure that takes 2 parameters with not enough parameters';
GO

EXEC dbo.pB @x = 1, @y = 2, @z = 3; 
PRINT '### Calling procedure that takes 2 parameters with too many parameters';
GO

Tutti questi producono errori di livello di gravità 16 e tutti procedono con il batch, come evidenziato dall'output di stampa:

Messaggio 8146, livello 16, stato 2, procedura pA, riga 11 La
procedura pA non ha parametri e sono stati forniti argomenti.
### La procedura di chiamata che non accetta parametri con un parametro
Msg 201, Livello 16, Stato 4, Procedura pB, Riga 14 La
procedura o la funzione 'pB' prevede il parametro '@x', che non è stato fornito.
### La procedura di chiamata che accetta 2 parametri senza parametri
Msg 201, Livello 16, Stato 4, Procedura pB, Riga 18 La
procedura o la funzione 'pB' prevede il parametro '@y', che non è stato fornito.
### La procedura di chiamata che accetta 2 parametri con parametri non sufficienti
Messaggio 8144, Livello 16, Stato 2, Procedura pB, Riga 22
Procedura o funzione pB ha troppi argomenti specificati.
### Procedura di chiamata che accetta 2 parametri con troppi parametri

Come sospettavo, ci sono eccezioni, ovviamente, come osservato nei commenti. L'errore di conversione è di gravità 16 ma interrompe il batch:

SET XACT_ABORT OFF;
SELECT CONVERT (INT, 'foo');
PRINT 'Made it.'; -- no print happens

I risultati non includono l'output di stampa questa volta:

Messaggio 245, livello 16,
conversione stato 1 non riuscita durante la conversione del valore varchar 'pippo' nel tipo di dati int.


Grazie mille! Pensavo che non sarei stato in grado di utilizzare il livello di gravità come indicatore a causa dell'incongruenza precedente. Molto felice di sapere che non è così.
Jamie Alford,

Aargh! Esistono ancora alcuni errori di livello 16 che interromperanno il batch. Se seleziono ed eseguo: inizio a tran print @@ TRANCOUNT print convert (int, 'abc') seguito da: print @@ TRANCOUNT Si verificherà un errore di livello 16 ma il batch verrà interrotto.
Jamie Alford, il

A proposito, se scopri casi in cui l'eccezione viene sollevata con una gravità diversa da quella dichiarata, ti preghiamo di segnalarli tramite connect
Remus Rusanu,

2

Oltre ai tipi di errori rilevati da @Aaron (ovvero Gravità> = 19 e errori di conversione), anche i seguenti tipi di errori, indicati nella pagina MSDN per TRY ... CATCH , interromperanno un batch:

I seguenti tipi di errori non sono gestiti da un blocco CATCH quando si verificano allo stesso livello di esecuzione del costrutto TRY… CATCH:

  • Compilare errori, come errori di sintassi, che impediscono l'esecuzione di un batch.

  • Errori che si verificano durante la ricompilazione a livello di istruzione, come errori di risoluzione dei nomi oggetto che si verificano dopo la compilazione a causa della risoluzione dei nomi posticipata.

Questi errori vengono riportati al livello in cui è stato eseguito il batch, la stored procedure o il trigger.

Negli esempi seguenti, tieni presente che tre di loro sono pari al livello di gravità 15.

ESEMPIO 1

SET XACT_ABORT OFF;
SELECT @NotDeclared; -- parse error
PRINT 'Do you see me?';

Ritorna:

Messaggio 137, livello 15, stato 2, riga 2 È
necessario dichiarare la variabile scalare "@NotDeclared".

ESEMPIO 2

SET XACT_ABORT OFF;
InvalidSQL; -- parse error
PRINT 'Do you see me?';

Ritorna:

Messaggio 102, livello 15, stato 1, riga 2
Sintassi errata vicino a "InvalidSQL".

ESEMPIO 3

SET XACT_ABORT OFF;
SELECT 1 -- statement preceding THROW not terminated by semicolon
THROW 50505, N'Error, yo', 1; -- parse error
PRINT 'Do you see me?';

Ritorna:

Messaggio 102, livello 15, stato 1, riga 3
Sintassi errata vicino a '50505'.

ESEMPIO 4

SET XACT_ABORT OFF;
SELECT NoSuchColumn FROM sys.objects; -- compilation error
PRINT 'Do you see me?';

Ritorna:

Messaggio 207, livello 16, stato 1, riga 3
Nome colonna non valido "NoSuchColumn".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.