Re: Unable to use INSERT ... RETURNING with column from other table

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>

 

In response to

Responses

Browse pgsql-sql by date

  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