Вы не можете иметь нулевой столбец в первичном ключе, но вместо этого вы можете создать уникальный индекс с нулевыми столбцами. Чтобы это работало в Oracle 10g, мне также пришлось явно добавить в таблицу уникальный запрет:
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);
Однако я попытался протестировать эту настройку, и она не работает так, как я ожидал. Например:
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
ОК, это то, что ожидается. Нет строки в родительском, поэтому строка не должна быть разрешена в дочерней таблице, однако:
SQL> insert into b1 values (2, null, 1);
1 row created.
Похоже, это просто позволяет вставить эту строку без сбоев, даже если в t1 нет строк с 2, вообще нулевым!
SQL> commit;
Commit complete.
SQL> select * from t1;
A1 A2 A3
---------- ---------- ----------
1 1
SQL> select * from b1;
B1 B2 B3
---------- ---------- ----------
2 1
Я был удивлен таким поведением, поскольку уникальный индекс на t1 ведет себя так, как вы ожидаете (только 1 строка может быть вставлена с 1, нулем и т. Д.).