2010-03-10 11 views
6

Ho due tabelle A e B come definito sotto.Come avere una combinazione di chiavi primarie che potrebbe avere valori nulli?

create table A 
(
    A_1 varchar2(10) NOT NULL, 
    A_2 varchar2(10), 
    A_3 varchar2(10), 
    constraint A_PK primary key (A_1,A_2) 
) 
TABLE A DATA 
A_1  |A_2 |A_3 
1111  abc  some_text1 
1111  null some_text1 
1112  abc  some_text2 
1113  def  some_text3 

    create table B 
    (
    B_1 varchar2(10) NOT NULL, 
    B_2 varchar2(10), 
    B_3 varchar2(10), 
    constraint B_PK primary key (B_1,B_2,B_3), 
    constraint B_FK foreign key (B_1,B2) references A(A_1,A_2) 
    ) 
TABLE B DATA 
B_1 | B_2 |B_3 
1111 abc  text1 
1111 null  text2 
1111 null  text3 
1111 null  text4 

colonna A_2 nella tabella A volte può essere nullo ma la combinazione di A_1 e A_2 è sempre unico. Ho bisogno che A_2 faccia parte della chiave primaria, perché solo io posso fare riferimento a A_1 e A_2 come chiavi esterne nella tabella B. Il problema qui è che la chiave primaria non può essere nullo. Come risolvere questo problema? Qualsiasi risposta sarà molto apprezzata

risposta

21

Si risolve questo problema non avendo questo come una chiave primaria. Le chiavi primarie non possono essere NULL o, se sono chiavi primarie composite, non possono contenere NULL. Rendilo invece un indice univoco. Creare un campo numeratore automatico per la chiave primaria.

2

Non è possibile avere una colonna null in una chiave primaria, ma è possibile invece creare un indice Unique con colonne null. Per arrivare a questo lavoro in Oracle 10g, ho anche dovuto aggiungere esplicitamente un contraint unica sul tavolo:

create table t1 (a1 integer not null, 
       a2 integer, 
       a3 integer); 

create unique index t1_uk1 on t1(a1, a2); 

alter table t1 add constraint t1_cuk1 unique (a1, a2); 

create table b1 (b1 integer not null, b2 integer, b3 integer); 

create index b1_idx1 on b1 (b1, b2); 

alter table b1 add constraint b1_fk1 
    foreign key (b1, b2) references t1 (a1, a2); 

Tuttavia, ho cercato prove della messa a punto, e non funziona come mi aspettavo che sarebbe stato. Ad esempio:

SQL> insert into t1 values (1, null, 1); 

1 row created. 

SQL> insert into b1 values (1, 1, 1); 
insert into b1 values (1, 1, 1) 
* 
ERROR at line 1: 
ORA-02291: integrity constraint (B1_FK1) violated - parent key not 
found 

OK, questo è ciò che è previsto. Nessuna riga nel genitore, quindi una riga non dovrebbe essere consentito nella tabella figlio, però:

SQL> insert into b1 values (2, null, 1); 

1 row created. 

sembra appena lasciato quella riga ottenere inserita senza venir meno, anche se non ci sono righe in T1 con 2, null affatto!

SQL> commit; 

Commit complete. 

SQL> select * from t1; 

     A1   A2   A3 
---------- ---------- ---------- 
     1      1 

SQL> select * from b1; 

     B1   B2   B3 
---------- ---------- ---------- 
     2      1 

Sono rimasto sorpreso da questo comportamento, come l'indice univoco su t1 si comporta come ci si aspetterebbe a (solo 1 riga può essere inserito con 1, null, ecc).

1

Se si utilizza "deferrabile inizialmente rinviato" sulla chiave primaria, è possibile avere valori NULL ...

Problemi correlati