Voici une petite expérience que j'ai courue dans une base de données Oracle (10g). Mis à part la commodité d'implémentation (Oracle), je ne peux pas comprendre pourquoi certaines insertions sont acceptées et d'autres rejetées.Comment puis-je contraindre plusieurs colonnes pour éviter les doublons, mais ignorer les valeurs nulles?
create table sandbox(a number(10,0), b number(10,0));
create unique index sandbox_idx on sandbox(a,b);
insert into sandbox values (1,1); -- accepted
insert into sandbox values (1,2); -- accepted
insert into sandbox values (1,1); -- rejected
insert into sandbox values (1,null); -- accepted
insert into sandbox values (2,null); -- accepted
insert into sandbox values (1,null); -- rejected
insert into sandbox values (null,1); -- accepted
insert into sandbox values (null,2); -- accepted
insert into sandbox values (null,1); -- rejected
insert into sandbox values (null,null); -- accepted
insert into sandbox values (null,null); -- accepted
En supposant qu'il est logique d'avoir de temps en temps quelques lignes avec une colonne de valeurs inconnues, je peux penser à deux cas d'utilisation possibles impliquant la prévention des doublons:
1. Je veux rejeter les doublons, mais accepter quand une contrainte La valeur de la colonne est inconnue.
2. Je souhaite rejeter les doublons, même dans les cas où la valeur d'une colonne contrainte est inconnue.
Apparemment, Oracle met en œuvre quelque chose de différent si:
3. Rejeter les doublons, mais accept (uniquement) lorsque toutes les valeurs de la colonne ne sont pas connus contraintes.
Je peux penser à des façons d'utiliser l'implémentation d'Oracle pour utiliser case (2) - par exemple, avoir une valeur spéciale pour "unknown", et rendre les colonnes non-nulles. Mais je n'arrive pas à comprendre comment utiliser le cas (1). En d'autres termes, comment Oracle peut-il agir comme cela?
create table sandbox(a number(10,0), b number(10,0));
create unique index sandbox_idx on sandbox(a,b);
insert into sandbox values (1,1); -- accepted
insert into sandbox values (1,2); -- accepted
insert into sandbox values (1,1); -- rejected
insert into sandbox values (1,null); -- accepted
insert into sandbox values (2,null); -- accepted
insert into sandbox values (1,null); -- accepted
insert into sandbox values (null,1); -- accepted
insert into sandbox values (null,2); -- accepted
insert into sandbox values (null,1); -- accepted
insert into sandbox values (null,null); -- accepted
insert into sandbox values (null,null); -- accepted
exemple parfait d'une bonne question (plus il est celui que je avais besoin répondu!) – orbfish