鉴于PostgreSQL中的下表,如何插入引用自身的记录?
CREATE TABLE refers (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
parent_id INTEGER NOT NULL,
FOREIGN KEY (parent_id) REFERENCES refers(id)
);
我在Web上找到的示例允许parent_id为NULL,然后使用触发器来更新它。如果可能的话,我宁愿一次更新。
答案 0 :(得分:10)
您可以从序列中选择last_value,这是在使用serial:
类型时自动创建的create table test (
id serial primary key,
parent integer not null,
foreign key (parent) references test(id)
);
insert into test values(default, (select last_value from test_id_seq));
insert into test values(default, (select last_value from test_id_seq));
insert into test values(default, (select last_value from test_id_seq));
select * from test;
id | parent
----+--------
1 | 1
2 | 2
3 | 3
(3 rows)
以下更简单似乎也有效:
insert into test values(default, lastval());
虽然我不知道在使用多个序列时这是如何工作的......我查了一下; lastval()返回最后一个返回值,或者使用最后一个nextval或setval调用设置任何序列,所以以下内容会让你遇到麻烦:
create table test (
id serial primary key,
foo serial not null,
parent integer not null,
foreign key (parent) references test(id)
);
select setval('test_foo_seq', 100);
insert into test values(default, default, lastval());
ERROR: insert or update on table "test" violates foreign key constraint "test_parent_fkey"
DETAIL: Key (parent)=(101) is not present in table "test".
但是以下情况可以接受:
insert into test values(default, default, currval('test_id_seq'));
select * from test;
id | foo | parent
----+-----+--------
2 | 102 | 2
(1 row)
答案 1 :(得分:2)
主要问题是 - 你为什么要插入与自身相关的记录?
Schema看起来像标准邻接列表 - 在关系数据库中实现树的方法之一。
事实上,在大多数情况下,您只需要为顶级元素使用parent_id NULL 。这实际上更容易处理。