J'ai eu la maladresse de croire que Le type ENUM de Mysql pouvait servir de garde fou.

En effet

[SQL]
create table `test_enum`( 
`id` int UNSIGNED NOT NULL AUTO_INCREMENT , 
`monEnum` enum('a','brol','7') , 
`monAutreEnum` enum('a','brol','7') NOT NULL , 
PRIMARY KEY (`id`)
)  ;

Je ne veux que 'a','brol' ou '7', éventuellement NULL dans monEnum

insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'a','a');
# (1 row(s) affected)


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,NULL,'a');
# (1 row(s) affected)


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'a',NULL);
# Error Code : 1048
# Column 'monAutreEnum' cannot be null


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,NULL,NULL);
# Error Code : 1048
# Column 'monAutreEnum' cannot be null
    id  monEnum  monAutreEnum
------  -------  ------------
     1  a        a           
     2  a        a           
     3  (NULL)   a

Là ca allait.

Mais maintenant

[SQL]
insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'','a');
# (1 row(s) affected, 1 warning(s))


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'a','');
# (1 row(s) affected, 1 warning(s))


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'','');
# (1 row(s) affected, 2 warning(s))


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'Z','a');
# (1 row(s) affected, 1 warning(s))


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'a','Z');
# (1 row(s) affected, 1 warning(s))


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'Z','Z');
# (1 row(s) affected, 2 warning(s))

On voit que les "vides" et les "Z" ne bloquent pas l'ajout de l'enregistrement. et sont remplacés par "vide" alors que ce n'est pas une valeur acceptée.

En effet le manuel dit ceci.

Si vous insérez une valeur illégale dans une énumération ENUM (c'est à dire, une chaîne qui n'est pas dans la liste de valeurs autorisées), la chaîne vide est insérée pour représenter une erreur. Cette chaîne peut être distinguée d'une chaîne vide 'normale' par le fait que cette chaîne à la valeur numérique 0. Nous reviendrons sur ce point plus tard.

Par exemple, une colonne créée comme ENUM("un", "deux", "trois") peut prendre n'importe quelle valeur ci-dessous. L'index de chaque valeur est aussi présenté :

 Valeur     Index
--------- --------
 NULL 	   NULL
 ""         0
 "un"       1
 "deux"     2
 "trois"    3
[Resultat]
    id  monEnum  monAutreEnum
------  -------  ------------
     1  a        a           
     2  a        a           
     3  (NULL)   a           
     4           a           
     5  a                    
     6                       
     7           a           
     8  a                    
     9                       

Notez que si j'ajoute une valeur par défaut, ca n'y change rien

[SQL]
alter table `test_enum` 
change `monEnum` `monEnum` enum('a','brol','7') character set latin1 collate latin1_swedish_ci default 'a' NULL , 
change `monAutreEnum` `monAutreEnum` enum('a','brol','7') character set latin1 collate latin1_swedish_ci default 'a' NOT NULL;


///[SQL]
insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'','a');
# (1 row(s) affected, 1 warning(s))


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'a','');
# (1 row(s) affected, 1 warning(s))


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'','');
# (1 row(s) affected, 2 warning(s))


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'Z','a');
# (1 row(s) affected, 1 warning(s))


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'a','Z');
# (1 row(s) affected, 1 warning(s))


insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'Z','Z');
# (1 row(s) affected, 2 warning(s))
    id  monEnum  monAutreEnum
------  -------  ------------
     1  a        a           
     2  a        a           
     3  (NULL)   a           
     4           a           
     5  a                    
     6                       
     7           a           
     8  a                    
     9                       
    10           a           
    11  a                    
    12                       
    13           a           
    14  a                    
    15                       

En fait tout dépends du mode sql en cours

[SQL]
select @@SQL_MODE;
SET SESSION sql_mode='STRICT_ALL_TABLES';
select @@SQL_MODE;
#@@SQL_MODE       
#-----------------
#STRICT_ALL_TABLES

insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'brol','z');
#Error Code : 1265
#Data truncated for column 'monAutreEnum' at row 1
insert into `test_enum`(`id`,`monEnum`,`monAutreEnum`) values ( NULL,'z','brol');
#Error Code : 1265
#Data truncated for column 'monEnum' at row 1

SET SESSION sql_mode='';
select @@SQL_MODE;

Là mes 2 inserts sont bloqués avec le message