Impostare un SQL_MODE restrittivo

English version

Sviluppare Stored Routine, Trigger o Evente per MariaDB e MySQL non è facile, perché il linguaggio manca di flessibilità e ha molte limitazioni. In più, il server tenta di facilitarci la vita nascondendoci gli errori e permettendo cattive pratiche. Secondo la mia modesta opinione, se si devono scrivere più di 3 righe, le cattive pratiche rendono le cose esponenzialmente più ardue. Quando il server si lamenta perché hai fatto qualcosa di sbagliato, il problema non è nel server stesso: è nel tuo codice! E rimane lì anche se dici al server di tacere. L’unica soluzione ragionevole è trovare il problema e modificare il codice. Perciò suggerisco di far sì che il server sia petulante. Per fare questo, occorre modificare il valore della variabile SQL_MODE.

L’SQL_MODE può modificare SQL syntax, rendendola più compatibile con altri DBMS. Personalmente non amo usare sintassi che non siano standard de facto, ma credo sia una pratica innocua.

Alcuni flag però dovrebbero sempre essere impostati, perché fanno sì che il server non sia eccessivamente flessibile.

ERROR_FOR_DIVISION_BY_ZERO
I numeri non possono essere divisi per zero, perché il risultato non è definito. Se si tenta di eseguire tale operazione, la maggioranza dei linguaggi risponde con un errore. Lo fa anche MariaDB, se questo flag è impostato. Altrimenti, restituisce NULL. Siccome il valore NULL corretto, da un punto di vista logico, per rappresentare un valore non definito, questo comportamento potrebbe andare bene. Ma di solito non è una cosa desiderata – se si divide per zero per errore, è bene esserne informati e correggere il bug!

NO_AUTO_CREATE_USER
Quando si utilizza GRANT per assegnare dei permessi a un utente che non esiste, esso viene creato automaticamente, a meno che questo flag sia impostato. Dal punto di vista della sicurezza, non è una buona cosa che si possa creare un utente per errore.

NO_AUTO_VALUE_ON_ZERO
Questo flag permette di inserire il valore 0 in un campo AUTO_INCREMENT. Poiché 0 è un valore lecito, in genere questo flag dovrebbe essere impostato. Ma non me ne curo molto, perché modificare una colonna AUTO_INCREMENT è secondo me una cattiva pratica.

NO_ENGINE_SUBSTITUTION
Quando si crea una tabella, è importante scegliere lo Storage Engine più appropriato. Se questo flag non è impostato, e si specifica uno Storage Engine che non esiste, il server utilizzerà quello di default.

NO_ZERO_DATE
Se questo flag non è impostato, MariaDB accetta un valore data speciale: ‘0000-00-00’. Se si desidera utilizzarlo, non occorre impostare questo flag; ma non è una situazione comune. In caso contrario è soltanto una fonte di problemi, perché le date non valide verranno convertite in date-zero senza avviso. E questo non è quasi mai ciò che si vuole che accada.

NO_ZERO_IN_DATE
Questo flag impedisce che le date non-zero possano contenere delle parti-zero, come ‘0000-05-20’ o ‘1994-00-01′. E’ un po’ meno usuale creare una data di questo genere per errore, ma può accadere se si compone dinamicamente una data come stringa.

ONLY_FULL_GROUP_BY
Quando si specifica una colonna non aggregata e non raggruppata in una clausola SELECT, il risultato non è definito. Per questo motivo dovrebbe essere generato un errore, ma ciò accade solo se questo flag è impostato.

STRICT_ALL_TABLES
Questo flag è molto importante perché, se non è impostato, non viene generato alcun errore quando si tenta di inserire un valore fuori dall’intervallo consentivo (o una stringa troppo lunga). Funziona non soltanto per le tabelle, ma anche per le variabili e le funzioni. Per esempio, se una funzione dichiarata come TINYINT SIGNED tenta di restituire 200, non viene generato alcun errore (solo un warning), e il valore restituito è 127. Un problema di questo genere può essere difficile da debuggare.

STRICT_TRANS_TABLES
Vedi STRICT_ALL_TABLES, ma questo flag funziona solo per le tabelle transazionali.

Per questi motivi, l’SQL_MODE che ho deciso di utilizzare per scrivere le Stored Routine dei progetti STK è il seguente:

SET @@session.SQL_MODE = 'ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY,STRICT_ALL_TABLES,STRICT_TRANS_TABLES';

Qui troverete una lista di tutti i flag di SQL_MODE in MySQL.

Un’altra ottima pratica è attivare lo Strict Mode di InnoDB, ma questo esula dagli scopi di questo post.

A presto!

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...