如何从INSERT返回值,而不是插入的行

时间:2016-06-15 06:06:14

标签: sql postgresql postgresql-9.5

我有大量的行要同时插入到PostgreSQL数据库中。我需要跟踪为插入的每一行分配的id。例如,我们有表:

CREATE TABLE example
(
  id serial,
  name text,
  CONSTRAINT example_pkey PRIMARY KEY (id),
);

现在我有一些我不想插入的id的数据(因为序列id列将分配一个新的id),但我需要跟踪旧id和新id之间的映射:

old id | name
-------------
-1     | foo
-2     | bar
-3     | baz

所以我写了这个查询

WITH data(oldid,name) AS ( VALUES
    (-1,'foo'),
    (-2,'bar'),
    (-3,'baz')
)
INSERT INTO example(name)
SELECT name FROM data d
RETURNING id, d.oldid

期待得到回报:

id  | oldid
-----------
1   | -1
2   | -2
3   | -3

但是这不起作用,因为我不相信你可以返回一个未插入的列。有没有其他方法可以做到这一点?

3 个答案:

答案 0 :(得分:1)

我最终创建了一个包含单行插入的函数:

CREATE OR REPLACE FUNCTION add_example(
    in_name text)
  RETURNS integer AS
$BODY$
DECLARE
 new_id integer;
BEGIN
    INSERT INTO example(name)
    VALUES (in_name) RETURNING id INTO new_id;
    RETURN new_id;
END;
$BODY$
LANGUAGE plpgsql;

然后我可以做:

WITH data(oldid, name) AS (VALUES
    (-1,'foo'),
    (-2,'bar'),
    (-3,'baz')
)
SELECT oldid, add_example(name) AS id
FROM data

返回我期望的内容。我想看看是否可以在没有该功能的情况下完成。

答案 1 :(得分:0)

 CREATE SEQUENCE data_id_seq;

 CREATE TABLE DATA (
      id integer default nextval('data_id_seq') NOT NULL PRIMARY KEY,
      oldid integer,
      name text,
 );

 INSERT INTO DATA(oldid,name) values (-1,'foo'),(-2,'bar'),(-3,'baz') returning id,oldid;

答案 2 :(得分:0)

  

可选的RETURNING子句导致INSERT计算并返回   基于实际插入的每一行的值

来自https://www.postgresql.org/docs/current/static/sql-insert.html

所以这种解决方案不可避免地存在色谱柱寄生虫:

alter table example add column old bigint;

WITH d(oldid,name) AS ( VALUES
    (-1,'foo'),
    (-2,'bar'),
    (-3,'baz')
)
INSERT INTO example(name,old)
SELECT "name", oldid FROM d
RETURNING id, old