给出如下表:
CREATE TABLE public.parenttest (
id bigserial NOT NULL PRIMARY KEY,
mydata varchar(30),
parent bigint
) WITH (
OIDS = FALSE
);
我想插入一堆行。其中一些行应该将之前插入的行的序列生成id
作为列parent
的值。
例如:
INSERT INTO parenttest (mydata,parent) VALUES ('rootnode',null);
INSERT INTO parenttest (mydata,parent) VALUES ('child1', /*id of rootnode*/);
INSERT INTO parenttest (mydata,parent) VALUES ('child2', /*id of rootnode*/);
INSERT INTO parenttest (mydata,parent) VALUES ('child2.1', /*id of child 2*/);
INSERT INTO parenttest (mydata.parent) VALUES ('child2.2', /*id of child 2*/);
...应该产生以下数据集(id,mydata,parent)
1,'rootnode',null
2,'child1',1
3,'child2',1
4,'child2.1',3
5,'child2.2',3
UNTIL child2.2
,当我使用
SELECT currval('parenttest_id_seq');
获取父级id
,但当然我得到的是child2.2
的ID。
对我来说很重要的是,我可以尽可能少地使用客户端请求来完成所有必要的工作 - 我想在服务器端执行所有id生成。
答案 0 :(得分:1)
如果行可以短暂地拥有NULL
父级,那么我就是这样做的。
INSERT INTO parenttest (mydata) VALUES
('rootnode'),
('child1'),
('child2'),
('child2.1'),
('child2.2');
UPDATE parenttest SET parent = (select id from parenttest pt where
(pt.mydata = 'rootnode' and parenttest.mydata in ('child1','child2')) or
(pt.mydata = 'child2' and parenttest.mydata in ('child2.1','child2.2')))
WHERE
mydata in ('child1',
'child2',
'child2.1',
'child2.2');
答案 1 :(得分:1)
你可以做一些丑陋的事情:
INSERT INTO parenttest (mydata,parent) VALUES ('rootnode',null);
INSERT INTO parenttest (mydata,parent) SELECT 'child1', id FROM parenttest WHERE mydata='rootnode';
INSERT INTO parenttest (mydata,parent) SELECT 'child2', id FROM parenttest WHERE mydata='rootnode';
INSERT INTO parenttest (mydata,parent) SELECT 'child2.1', id FROM parenttest WHERE mydata='child2';
INSERT INTO parenttest (mydata.parent) SELECT 'child2.2', id FROM parenttest WHERE mydata='child2';
我认为在这里做正确的事情是使用客户端,在插入后检索'rootnode'的id,然后在INSERT语句中显式发送以下两个语句及其id。
答案 2 :(得分:0)
经过一些实验,我发现了一个使用匿名PL / PgSQL代码块的解决方案:
DO $$DECLARE
parentid bigint;
BEGIN
INSERT INTO parenttest (mydata) VALUES ('rootnode');
parentid:=currval('parenttest_id_seq');
INSERT INTO parenttest (mydata,parent) VALUES ('child 1',parentid);
INSERT INTO parenttest (mydata,parent) VALUES ('child 2',parentid);
parentid:=currval('parenttest_id_seq');
INSERT INTO parenttest (mydata,parent) VALUES ('child 2.1',parentid),('child 2.2',parentid);
END$$;
可以在客户端的单个请求中使用它,我不必在客户端生成任何内容,因此这可能是我的问题的一种可能的解决方案。
编辑: 它可以用这样表达:
DO $$DECLARE
parentid bigint;
BEGIN
INSERT INTO parenttest (mydata) VALUES ('Flat') RETURNING id INTO parentid;
INSERT INTO parenttest (mydata, parent) VALUES ('Subflat 1', parentid);
INSERT INTO parenttest (mydata, parent) VALUES ('Subflat 2', parentid)RETURNING id INTO parentid;
INSERT INTO parenttest (mydata, parent) VALUES ('Subflat 2.1', parentid), ('Subflat 2.2', parentid);
END$$;