插入新记录并将结果主键用于另一个INSERT

时间:2014-07-31 18:13:37

标签: sql postgresql plpgsql common-table-expression sql-insert

如果我想从单个插页中保存主键(mytable_id),我已完成以下操作:

CREATE OR REPLACE FUNCTION myfunct(ownerid text) RETURNS void AS 
$$
DECLARE myvar INTEGER;

BEGIN

INSERT INTO mytable (long_description) VALUE 'testing';

SELECT CURRVAL('mytable_mytable_id_seq') INTO myvar;

END;
$$ 
LANGUAGE plpgsql;

问题是,我现在想在多个插页上执行相同的操作。我想插入一行,并采用新插入的行PK并将其用作另一个插入中的外键。

所以我有

DECLARE myvar2 INTEGER;

INSERT INTO mytable (long_description)
SELECT DISTINCT type FROM schema1.myothertable WHERE type IS NOT NULL;

INSERT INTO mytable2 (foreign_key1, foregin_key2)
VALUES (myvar, myvar2); -- somewhere pk from mytable is stored in myvar2

有没有办法在同一个查询中执行这两个插入? 我想避免循环,但我不确定没有它就可以完成。

2 个答案:

答案 0 :(得分:0)

抱歉,如果我没有找到你的话。但为什么不一次使用nextval呢? Postgres函数总是事务,所以如果你这样做就没有危险:

CREATE OR REPLACE FUNCTION myfunct(ownerid text) RETURNS void AS 
$$
DECLARE 
     nextId INTEGER;
BEGIN
     SELECT nextval('mytable_mytable_id_seq') INTO nextId;
     INSERT INTO mytable (id, long_description) values (nextId, 'testing');
     INSERT INTO othertable (id, whatever) values (nextId, 'whatever');
 END;
 $$
 LANGUAGE plpgsql;

您可以使用相同的pk / fk插入任何您想要的内容。

答案 1 :(得分:0)

使用 data-modifying CTEs 在一个语句中完成所有操作。这是最快,最干净的。如果你想要,你可以在函数中包含...

WITH ins AS (
   INSERT INTO mytable (long_description)
   SELECT DISTINCT type
   FROM   schema1.myothertable
   WHERE  type IS NOT NULL
   RETURNING *
   )
INSERT INTO mytable2 (foreign_key1, foregin_key2)
SELECT 'myvar', ins.mytable_id
FROM   ins
RETURNING *;            -- optional

在这个相关答案中有更多解释: