Hier ist ein kleines Experiment, das ich in einer Oracle-Datenbank (10g) ausgeführt habe. Abgesehen von (Oracles) Implementierungskomfort kann ich nicht herausfinden, warum einige Einfügungen akzeptiert und andere zurückgewiesen werden.Wie kann ich mehrere Spalten einschränken, um Duplikate zu verhindern, aber Nullwerte ignorieren?
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
Unter der Annahme, dass es Sinn macht, einige Zeilen gelegentlich zu haben, mit einigen Spalte unbekannte Werte, kann ich mir vorstellen zwei mögliche Anwendungsfälle beteiligt zu verhindern Duplikate:
1. Ich Duplikate verwerfen wollen, aber akzeptieren, wenn eine eingeschränkte Der Wert der Spalte ist unbekannt.
2. Ich möchte Duplikate ablehnen, auch wenn der Wert einer eingeschränkten Spalte unbekannt ist.
Offenbar implementiert Oracle etwas anderes aber:
3. Duplikate ablehnen, aber akzeptieren (nur), wenn alle eingeschränkten Spaltenwerte unbekannt sind.
Ich kann mir überlegen, wie man die Implementierung von Oracle nutzen kann, um case (2) zu verwenden - zum Beispiel einen speziellen Wert für "unknown" und die Spalten nicht nullbar zu machen. Aber ich kann nicht herausfinden, wie man den Fall (1) benutzt.
Mit anderen Worten, wie kann ich Oracle dazu bringen, so zu handeln?
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
perfektes Beispiel für eine gute Frage (plus es ist ein antwortete ich gebraucht!) – orbfish