2010-03-10 68 views
6

Tôi có hai bảng A và B như được định nghĩa dưới đây.Làm cách nào để có tổ hợp khóa chính có thể có giá trị null?

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 

Cột A_2 trong bảng A đôi khi có thể rỗng nhưng kết hợp A_1 và A_2 luôn là duy nhất. Tôi cần A_2 là một phần của khóa chính vì sau đó chỉ có tôi mới có thể tham chiếu A_1 và A_2 chúng dưới dạng khóa ngoài trong bảng B. Vấn đề ở đây là khóa chính không thể rỗng. Làm thế nào để giải quyết vấn đề này? Bất kỳ phản hồi nào sẽ được đánh giá cao

Trả lời

21

Bạn giải quyết vấn đề này bằng cách không có điều này làm khóa chính. Các khóa chính không thể là NULL hoặc nếu chúng là các khóa chính hỗn hợp, không được chứa NULL. Biến nó thành một chỉ mục duy nhất thay thế. Tạo trường tự động cho khóa chính.

2

Bạn không thể có cột rỗng trong khóa chính, nhưng thay vào đó bạn có thể tạo một chỉ mục duy nhất có cột rỗng. Để có được điều này để làm việc trong Oracle 10g, tôi cũng đã có thêm một cách rõ ràng contraint độc đáo trên bàn:

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); 

Tuy nhiên, tôi đã cố gắng thử nghiệm thiết lập này ra, và nó không hoạt động như tôi mong đợi nó sẽ. Ví dụ:

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, vì vậy đó là những gì được mong đợi. Không hàng trong phụ huynh, do đó, một hàng nên không được phép trong bảng con, tuy nhiên:

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

1 row created. 

Hình như nó chỉ để cho hàng đó được chèn mà không thất bại, mặc dù không có hàng trong t1 với 2, null ở tất cả!

SQL> commit; 

Commit complete. 

SQL> select * from t1; 

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

SQL> select * from b1; 

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

Tôi đã ngạc nhiên bởi hành vi này, vì chỉ mục duy nhất trên t1 hoạt động như bạn mong đợi (chỉ 1 hàng có thể được chèn với 1, null, v.v.).

1

Nếu bạn sử dụng "trì hoãn ban đầu trì hoãn" trên khóa chính, bạn có thể CÓ giá trị NULL ...

Các vấn đề liên quan