我有两个表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中的A_2列有时可能为空,但A_1和A_2的组合始终是唯一的。我需要A_2是主键的一部分,因为只有这样我才能引用A_1和A_2,它们作为表B中的外键。这里的问题是主键不能为空。如何解决这个问题?任何回应都将受到高度赞赏
4条答案
按热度按时间ocebsuys1#
解决这个问题的方法是不使用this作为主键。主键不能是
NULL
,或者如果它们是复合主键,则不能包含NULL
。请将其改为唯一索引。为主键创建一个自动编号字段。9w11ddsr2#
主键中不能有null列,但可以创建一个包含null列的Unique索引。为了让它在Oracle 10 g中工作,我还必须在表中显式添加一个unique constraint:
然而,我试着测试这个设置,它并不像我预期的那样工作。例如:
好了,这就是我们所期望的。父表中没有行,所以子表中不允许有行,但是:
看起来它只是让该行被插入而没有失败,即使t1中根本没有2,null的行!
我对这种行为感到惊讶,因为t1上的唯一索引的行为与您所期望的一样(只能插入1行,1,null等)。
ioekq8ef3#
如果你在主键上使用“deferable initial deferred”,你可以有NULL值...
u7up0aaq4#
从技术上讲,你可以创建一个复合主键,其中一部分被标记为可空。你也可以从另一个表中引用它,并使它成为其复合主键的一部分。
以下语句在Oracle中是合理的:
您也可以在上述表格中插入值。
但是,由于
primary key
约束的存在,您仍然不能在A_2
或B_2
中插入空值。在标记为
null
的列上设置primary key
和在标记为not null
的列上设置primary key
之间有一个核心区别。在后一种情况下,如果禁用
primary key
(通过使用:ALTER TABLE A DISABLE PRIMARY KEY;
),您仍然有一个check constraint
存在(对于每个不可空的列),这将防止空插入。