如何 return 来自 INSERT 的值,而不是插入的行
How to return values from INSERT other that the row that was inserted
我有大量行要同时插入到 PostgreSQL 数据库中。我需要跟踪为插入的每一行分配的 id。例如假设我们有 table:
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
但是这不起作用,因为我不相信您可以 return 未插入的列。有没有其他方法可以做到这一点?
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;
The optional RETURNING clause causes INSERT to compute and return
value(s) based on each row actually inserted
来自 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
我最终创建了一个包含单行插入的函数:
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
returns 我所期望的。不过,我想看看是否可以在没有该功能的情况下完成此操作。
我有大量行要同时插入到 PostgreSQL 数据库中。我需要跟踪为插入的每一行分配的 id。例如假设我们有 table:
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
但是这不起作用,因为我不相信您可以 return 未插入的列。有没有其他方法可以做到这一点?
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;
The optional RETURNING clause causes INSERT to compute and return value(s) based on each row actually inserted
来自 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
我最终创建了一个包含单行插入的函数:
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
returns 我所期望的。不过,我想看看是否可以在没有该功能的情况下完成此操作。