Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

SQLSTATE è un codice di cinque caratteri che classifica una condizione prodotta da un’istruzione SQL. In un errore come ERROR 1146 (42S02), 1146 è il numero specifico di MySQL e 42S02 è lo SQLSTATE. Non è, di per sé, un “segnale”: SIGNAL è invece l’istruzione MySQL che può generare una condizione personalizzata.

Come leggere un errore MySQL

Un errore restituito dal client MySQL presenta spesso questa forma:

ERROR 1146 (42S02): Table 'test.no_such_table' doesn't exist
Parte Esempio Significato
Numero errore 1146 Identifica un errore secondo la codifica specifica di MySQL.
SQLSTATE 42S02 Classifica la condizione con un codice di cinque caratteri più standardizzato.
Messaggio Table 'test.no_such_table' doesn't exist Descrive la condizione in testo leggibile; è utile per il debugging, ma può dipendere da versione e driver.

Il numero e lo SQLSTATE sono due informazioni distinte sullo stesso evento: non sono intercambiabili. MySQL descrive gli elementi dei messaggi di errore nel manuale di riferimento.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Che cosa indicano le classi SQLSTATE

Uno SQLSTATE è composto da cinque caratteri alfanumerici. I primi due individuano la classe generale della condizione; gli altri tre la specificano ulteriormente. Le classi principali distinguono successo, avviso, assenza di risultati ed eccezioni.

  • 00: successo. 00000 è il valore normalmente restituito dalle API quando l’istruzione è riuscita.
  • 01: avviso. L’istruzione può essere stata eseguita, ma ha prodotto una condizione diagnostica non trattata come eccezione.
  • 02: condizione “not found”, come l’assenza di righe in un contesto che si aspettava un risultato.
  • Classi superiori a 02: condizioni di eccezione, normalmente errori da gestire.

La classificazione è utile anche nelle stored procedure: un handler NOT FOUND può gestire la fine di un cursore, mentre SQLEXCEPTION intercetta le condizioni di eccezione. Le classi non descrivono da sole la causa concreta: per quella servono anche il numero MySQL e il messaggio. Per i dettagli su classi e condizioni, consultare le sezioni ufficiali su elementi degli errori e SIGNAL.

SQLSTATE e numero errore MySQL: quale usare?

Dato Quando è utile Limite
SQLSTATE Per gestire una categoria di condizioni con una logica più standardizzata e, in genere, più portabile tra database e driver. Può raggruppare cause diverse e non sempre è abbastanza specifico da solo.
Numero errore MySQL Per distinguere un errore specifico quando l’applicazione è legata a MySQL. È specifico del prodotto; i codici client e server non hanno necessariamente lo stesso significato.
Messaggio testuale Per log e diagnosi da parte degli sviluppatori. Può variare con versione, lingua, contesto o driver; non è una base affidabile per i confronti nel codice.

Una regola pratica è usare SQLSTATE per la categoria, il numero MySQL quando serve il dettaglio proprietario e il messaggio per la diagnostica. Registrare tutte e tre le informazioni aiuta a ricostruire l’evento senza basare il flusso del programma sul confronto di una frase.

SQLSTATE MySQL comuni

Questi valori sono esempi frequenti o rappresentativi, non una mappatura completa di tutti gli errori possibili. Il significato preciso può dipendere dal server e dal driver.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
SQLSTATE Uso tipico
23000 Violazione di integrità, per esempio una chiave duplicata o un vincolo non rispettato.
42000 Errore di sintassi o violazione di accesso.
42S02 Tabella o vista non trovata, come nell’esempio ERROR 1146 (42S02).
42S22 Colonna non trovata.
22001 Dato troppo lungo per la colonna.
22007 Formato di data o ora non valido.
HY000 Errore generale: non identifica una causa specifica.
45000 Eccezione generica definita dall’utente, spesso usata con SIGNAL.

HY000 merita particolare cautela: MySQL può usarlo quando non c’è uno SQLSTATE più specifico, e anche gli errori lato client possono ricadere in questa categoria. Se il codice è HY000, controllare il numero errore, il messaggio e il contesto anziché interpretarlo come una diagnosi.

Rank #2
MySQL Pocket Reference
  • Used Book in Good Condition

Come recuperare lo SQLSTATE

Dal client MySQL

Per consultare gli errori o le condizioni diagnostiche dell’ultima istruzione nella sessione, usare:

SHOW ERRORS;
SHOW WARNINGS;

SHOW ERRORS mostra gli errori; SHOW WARNINGS mostra le condizioni diagnostiche, inclusi gli avvisi.

Con GET DIAGNOSTICS

GET DIAGNOSTICS consente di leggere valori come SQLSTATE, messaggio e numero MySQL dall’area diagnostica. Per esempio, dopo un’istruzione che genera un errore:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
DROP TABLE test.no_such_table;

GET DIAGNOSTICS CONDITION 1
    @sqlstate = RETURNED_SQLSTATE,
    @message = MESSAGE_TEXT;

SELECT @sqlstate, @message;

Per l’esempio, il risultato concettuale è 42S02 insieme al messaggio relativo alla tabella mancante. I valori disponibili includono anche MYSQL_ERRNO, il numero di condizioni e il numero di righe interessate. La sintassi e le aree diagnostiche sono documentate in GET DIAGNOSTICS.

In un handler di stored procedure

Un handler può leggere la condizione che lo ha attivato con GET STACKED DIAGNOSTICS:

CREATE PROCEDURE esempio()
BEGIN
    DECLARE v_sqlstate CHAR(5);
    DECLARE v_errno INT;
    DECLARE v_message TEXT;

    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        GET STACKED DIAGNOSTICS CONDITION 1
            v_sqlstate = RETURNED_SQLSTATE,
            v_errno = MYSQL_ERRNO,
            v_message = MESSAGE_TEXT;

        SELECT
            v_sqlstate AS sqlstate_value,
            v_errno AS mysql_errno,
            v_message AS message_text;
    END;

    SELECT * FROM tabella_inesistente;
END;

L’area stacked è disponibile nel contesto di un handler e permette di leggere la condizione originaria anche se altre istruzioni nell’handler modificano l’area diagnostica corrente. Se sono presenti più condizioni, non dare per scontato che la condizione numero 1 sia sempre quella più importante: verificare il numero di condizioni e leggere quella pertinente.

Dal codice applicativo

Le API e i driver possono esporre SQLSTATE, codice numerico e messaggio con nomi e strutture diversi. Per esempio, in Java JDBC SQLException offre getSQLState() e getErrorCode(); in PHP PDO si può consultare errorInfo(). In Python e Node.js i campi dipendono dal driver installato, quindi verificare la sua documentazione invece di assumere proprietà universali.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Nella MySQL C API, le funzioni corrispondenti sono distinte:

if (mysql_query(conn, "SELECT * FROM tabella_inesistente") != 0) {
    printf("SQLSTATE: %sn", mysql_sqlstate(conn));
    printf("Numero errore: %un", mysql_errno(conn));
    printf("Messaggio: %sn", mysql_error(conn));
}

La documentazione della C API descrive mysql_sqlstate(), mysql_errno() e mysql_error().

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Che cosa fa SIGNAL SQLSTATE?

SQLSTATE è il valore che classifica la condizione; SIGNAL è l’istruzione MySQL che la genera esplicitamente. È usata soprattutto in procedure, funzioni e trigger, ma può essere impiegata anche fuori da un handler.

SIGNAL SQLSTATE [VALUE] 'sqlstate_value'
    [SET nome_informazione = valore [, ...]];

Per rifiutare un valore non valido in una procedura:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
CREATE PROCEDURE crea_ordine(IN p_totale DECIMAL(10,2))
BEGIN
    IF p_totale <= 0 THEN
        SIGNAL SQLSTATE '45000'
            SET MESSAGE_TEXT = 'Il totale deve essere maggiore di zero';
    END IF;
END;

45000 è una generica eccezione definita dall’utente, non un codice che spiega da solo la regola violata. Il messaggio e la logica applicativa forniscono quel contesto. Con SIGNAL si possono impostare elementi diagnostici come MESSAGE_TEXT e MYSQL_ERRNO; quest’ultimo è un’estensione specifica di MySQL. Per la sintassi e gli elementi ammessi, vedere il manuale MySQL su SIGNAL.

Non usare SIGNAL SQLSTATE '00000' per creare un errore: la classe 00 indica successo e MySQL rifiuta tale uso.

Quando usare RESIGNAL

RESIGNAL si usa dentro un handler per rilanciare la condizione corrente, eventualmente modificandone alcuni elementi. Ad esempio:

CREATE PROCEDURE aggiorna_cliente(IN p_id INT)
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        RESIGNAL SET MESSAGE_TEXT = 'Errore durante l’aggiornamento del cliente';
    END;

    UPDATE clienti
    SET aggiornato_il = CURRENT_TIMESTAMP
    WHERE id = p_id;
END;

Sostituire il messaggio originale può rendere più difficile capire la causa tecnica. Per conservare il contesto utile, registrare l’errore originale e aggiungere semmai informazioni sull’operazione prima di rilanciarlo. MySQL distingue SIGNAL, che genera una condizione, da RESIGNAL, che interviene su una condizione gestita; la descrizione è nel capitolo ufficiale sul condition handling.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Errori pratici da evitare

  • Non confrontare il messaggio testuale per decidere il flusso del programma: lingua, versione e driver possono cambiarlo.
  • Non trattare HY000 come se descrivesse una causa precisa.
  • Non presumere che ogni numero errore MySQL abbia una corrispondenza SQLSTATE univoca e specifica.
  • Non confondere NOT FOUND con un errore fatale: può rappresentare semplicemente la fine di un cursore o l’assenza di righe.
  • Non considerare SQLSTATE un sistema di logging o una correzione: classifica la condizione, mentre il codice applicativo deve gestirla e il log deve conservare i dettagli utili.
  • SIGNAL, RESIGNAL e GET DIAGNOSTICS hanno restrizioni d’uso e non sono istruzioni da trattare come query preparabili tramite PREPARE/EXECUTE; consultare le restrizioni di condition handling per i dettagli della versione in uso.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.