Quando “ENUM” fa i capricci

Il tipo “ENUM” consente di definire una lista di valori da attribuire a un campo, una soluzione molto comoda quando i valori sono pochi e vogliamo evitare la creazione di una tabella di supporto. Vediamo però un esempio in cui le cose non vanno come dovrebbero.


mysql> CREATE TABLE test_enum (ID INT, strano ENUM('0','1'));
Query OK, 0 rows affected (0.38 sec)

Abbiamo creato una tabella con un campo ENUM che accetta i valori ‘0’ e ‘1’. Fin qui, tutto bene.


mysql> INSERT INTO test_enum VALUES (1,1);
Query OK, 1 row affected (0.28 sec)

Il primo inserimento dovrebbe fare quel che ci aspettiamo, cioè mettere ‘1’ nel campo ID e ‘1’ nel campo strano. Controlliamo:


mysql> SELECT * FROM test_enum;
+------+--------+
| ID | strano |
+------+--------+
| 1 | 0 |
+------+--------+
1 row in set (0.00 sec)

Uhm, no. Questo non è quel che volevamo. Come mai il campo strano ha uno zero mentre noi abbiamo inserito 1? Il motivo è che i valori di enum devono essere valori testuali e quindi andrebbero messi fra virgolette.

Va bene, ma cosa succede se invece mettiamo un numero? Succede che MySQL cerca di venirci incontro, interpretando il numero come “il valore che sta alla posizione indicata da quel numero”. Nel nostro caso, si trattava di 1, che identifica la prima posizione, che nel nostro caso era ‘0’. Ecco spiegato l’arcano. Questo meccanismo si rivela comodo quando i valori hanno una grafia dubbia, e quindi per evitare errori possiamo citarli per posizione invece che per nome:


nano ENUM('Dotto', 'Gongolo', 'Eolo', 'Brontolo', 'Mammolo', 'Pisolo', 'Cucciolo');

Ora l’istruzione


INSERT INTO nani set nano = 1

farà sì che il campo nano contenga ‘Dotto’, cioè il primo valore della serie.

Un tranello simile ci attende quando vogliamo utilizzare il valore di default di un campo. Sapete che ogni campo di una tabella MySQL può avere un valore di default, da usare quando si omette quella colonna in un inserimento.

Guardate la creazione di questa tabella, in cui mettiamo un valore di default per un campo ENUM.


mysql> CREATE TABLE test_enum2 (ID int, strano enum('0','1') NOT NULL DEFAULT 1 );
Query OK, 0 rows affected (0.01 sec)

Ora, se inseriamo un record che non contiene un valore per il campo “strano”, ci potremmo aspettare che tale campo assuma il valore ‘1’.


mysql> INSERT INTO test_enum2 (ID) VALUES (10);
Query OK, 1 row affected (0.00 sec)

Invece, anche questa volta, ci troviamo il valore ‘0’.


mysql> SELECT * FROM test_enum2;
+------+--------+
| ID | strano |
+------+--------+
| 10 | 0 |
+------+--------+
1 row in set (0.00 sec)

La spiegazione è la stessa. Anche per la definizione del valore di default, indicando un numero senza virgolette si intende la posizione nella lista, non il valore stesso.