У меня есть две таблицы A и B как определенный рев.
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
Столбец A_2 в таблице A может иногда быть пустым, но комбинация A_1 и A_2 всегда уникальна. Мне нужен A_2 быть частью первичного ключа, потому что затем только я могу сослаться на A_1 и A_2 их как внешние ключи в таблице B. Проблемой здесь является первичный ключ, не может быть пустым. Как решить эту проблему? Любой ответ будет высоко цениться
Эту проблему можно решить, если у вас нет этого первичного ключа. Первичные ключи не могут быть NULL
или, если они составные первичные ключи, не могут содержать NULL
. Вместо этого сделайте его уникальным индексом. Создайте поле автонумерации для первичного ключа.
Вы не можете иметь нулевой столбец в первичном ключе, но вы можете создать уникальный индекс с нулевыми столбцами вместо этого. Чтобы заставить это работать в 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, null вообще!
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, null и т.д.).