PostgreSQL:外键列中的NULL值

um6iljoc  于 2023-04-05  发布在  PostgreSQL
关注(0)|答案(2)|浏览(150)

在我的PostgreSQL数据库中,我有以下表(简化):

CREATE TABLE quotations (
  receipt_id bigint NOT NULL PRIMARY KEY
);

CREATE TABLE order_confirmations (
  receipt_id bigint NOT NULL PRIMARY KEY
  fk_quotation_receipt_id bigint REFERENCES quotations (receipt_id)
);

现在我的问题如下:
我有与以前的报价有关的订单(这很好,因为我可以通过使用FK字段将这样的订单附加到引用的报价中),但我也有从头开始的订单没有匹配的报价。FK字段将为NULL,当然,如果数据库允许的话。不幸的是,我在INSERT语句中尝试将fk_quotation_receipt_id设置为NULL时得到错误,因为违反了外键约束。
在设计这些表的时候,我还在使用PgSQL8.2,它允许NULL值,而现在我使用的是9.1.6,它不允许NULL值。
我希望的是一个**可选(或可空)**外键约束order_confirmationsfk_quotation_receipt_id)→ quotations (receipt_id)。我在官方的PgSQL文档中找不到任何提示,其他用户发布的类似问题已经很老了。
谢谢你的任何有用的提示。

hs1rzwqc

hs1rzwqc1#

我在9.3中纠正了一个遗漏的逗号,我相信它在9.1中也能正常工作

create table quotations (
    receipt_id bigint not null primary key
);

create table order_confirmations (
    receipt_id bigint not null primary key,
    fk_quotation_receipt_id bigint references quotations (receipt_id)
);

insert into order_confirmations (receipt_id, fk_quotation_receipt_id) values 
    (1, null);

Confirmation将包括:

INSERT 0 1
hi3rlvi2

hi3rlvi22#

我一直在努力记住这个例子,所以下面的原子例子可以帮助我记住:

drop table if exists t2;
drop table if exists t1;
create table t1 (
    id integer generated by default as identity primary key
);

create table t2 (
    id integer generated by default as identity primary key,
    t1_id int references t1(id)
);

insert into t1 values (1);

insert into t2 values (1, 1);    -- OK, 1 exists so accepted
insert into t2 values (2, null); -- OK, null is accepted
insert into t2 values (3, 2);    -- NOK, 2 is not accepted

如果你想禁止null的情况,那么它与外键无关,而是与列的声明有关**(观察新来的not null部分)**:

...
create table t2 (
    id integer generated by default as identity primary key,
    t1_id int not null references t1(id)
);
...

PS:大写字母保留字会降低SQL的可读性,请使用小写字母。

相关问题