From: | Andreas Joseph Krogh <andreas(at)visena(dot)com> |
---|---|
To: | pgsql-sql(at)postgresql(dot)org |
Subject: | Re: Unable to use INSERT ... RETURNING with column from other table |
Date: | 2017-10-25 00:21:19 |
Message-ID: | VisenaEmail.5f.363e3023a414a542.15f50dcaa73@tc7-visena |
Views: | Whole Thread | Raw Message | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-sql |
På onsdag 25. oktober 2017 kl. 00:49:05, skrev Andreas Joseph Krogh <
andreas(at)visena(dot)com <mailto:andreas(at)visena(dot)com>>:
På onsdag 25. oktober 2017 kl. 00:06:59, skrev Peter Geoghegan <pg(at)bowt(dot)ie
<mailto:pg(at)bowt(dot)ie>>:
On Tue, Oct 24, 2017 at 3:04 PM, Andreas Joseph Krogh
<andreas(at)visena(dot)com> wrote:
> insert into foo(id, name) values(1, 'one'), (2, 'two');
>
> insert into foo(id, name) select 3, f.name from foo f where f.id = 1
returning id, f.id;
>
> ERROR: missing FROM-clause entry for table "f"
> LINE 1: ...lect 3, f.name from foo f where f.id = 1 returning id, f.id;
>
> I'd like to return f.id and the inserted id, is this possible?
It's possible on 9.5+. You need to assign the target table an alias
using AS -- AS in not a noise word for INSERT (the grammar requires
it).
See the INSERT documentation.
I'm not sure how an alias for the target_table will help me here as I'm trying
to return a value not being inserted?
f.id is not inserted, only columns matching f.id.
What I want to accomplish is returning a value from INSERT which is part of
the SELECT-expression's FROM-clause, not part of the actual inserted columns:
My real-world use-case isn't quite this simple but this sample-case
illustrates the problem;
DROP TABLE IF EXISTS tbl_value; DROP TABLE IF EXISTS tbl_header; CREATE TABLE
tbl_header( idINTEGER PRIMARY KEY, name VARCHAR NOT NULL ); CREATE TABLE
tbl_value( idSERIAL PRIMARY KEY, header_id INTEGER NOT NULL REFERENCES
tbl_header(id),name VARCHAR NOT NULL ); INSERT INTO tbl_header(id, name) VALUES(
1, 'header_one'), (2, 'header_two'); INSERT INTO tbl_value(id, header_id, name)
VALUES(1, 1, 'value 1'),(2, 1, 'value 2'),(3, 1, 'value 3') , (4, 2, 'value 1'
),(5, 2, 'value 2'),(6, 2, 'value 3'); SELECT setval('tbl_value_id_seq', 6);
WITHupd_h(new_header_id, header_name, old_header_id) AS ( INSERT INTO
tbl_header(id,name) SELECT 3, h.name FROM tbl_header h WHERE h.id = 1 RETURNING
id,name, 1 -- need h.id here ) INSERT INTO tbl_value(header_id, name) SELECT
f.new_header_id, hv.nameFROM tbl_value hv JOIN tbl_header h ON hv.header_id = h
.idJOIN upd_h AS f ON hv.header_id = f.old_header_id ; select h.*, v.* from
tbl_headerh JOIN tbl_value v ON v.header_id = h.id ORDER BY h.id, v.id;
id name id header_id name 1 header_one 1 1 value 1 1 header_one 2 1 value 2 1
header_one 3 1 value 3 2 header_two 4 2 value 1 2 header_two 5 2 value 2 2
header_two 6 2 value 3 3 header_one 7 3 value 1 3 header_one 8 3 value 2 3
header_one 9 3 value 3
I need to return the value for h.id in the first INSERT:
WITH upd_h(new_header_id, header_name, old_header_id) AS ( INSERT INTO
tbl_header(id,name) SELECT 3, h.name FROM tbl_header h WHERE h.id = 1 RETURNING
id,name, h.id ) INSERT INTO tbl_value(header_id, name) SELECT f.new_header_id,
hv.nameFROM tbl_value hv JOIN tbl_header h ON hv.header_id = h.id JOIN upd_h AS
fON hv.header_id = f.old_header_id ;
This fails with:
ERROR: missing FROM-clause entry for table "h"
LINE 5: RETURNING id, name, h.id
Is what I'm trying to do possible? I'd like to avoid having to use temp-tables
and/or PLPgSQL for this as I need to insert many such values in large batches...
Thanks.
-- Andreas Joseph Krogh
CTO / Partner - Visena AS
Mobile: +47 909 56 963
andreas(at)visena(dot)com <mailto:andreas(at)visena(dot)com>
www.visena.com <https://www.visena.com>
<https://www.visena.com>
From | Date | Subject | |
---|---|---|---|
Next Message | David G. Johnston | 2017-10-25 01:56:02 | Re: Unable to use INSERT ... RETURNING with column from other table |
Previous Message | Andreas Joseph Krogh | 2017-10-24 22:49:05 | Re: Unable to use INSERT ... RETURNING with column from other table |