Pgx: How to get the "RETURNING" data in "INSERT"?

Created on 13 Apr 2018  Β·  6Comments  Β·  Source: jackc/pgx

How to get the "RETURNING" data in "INSERT",such as:

INSERT INTO "user" ("name", "phone") VALUES ('foo',  '12345678') RETURNING "id";

Most helpful comment

Run it with QueryRow instead of Exec.

All 6 comments

Run it with QueryRow instead of Exec.

@jackc This doesn't seem to work. I'm getting an error "Scan received the wrong number of arguments, got 12 but expected 1"
Looking at the row.fields with debugger There really is only one item in the fields The name of it is "row" and datatype is "record"

Hem. It seems that the pgx doesn't like it when the RETURNING is written as RETURNING (col1, col2) it only works with RETURNING col1, col2

Those two commands mean different things. RETURNING (col1, col2) returns rows with a single column of "record" type. RETURNING col1, col2 returns rows with two columns of col1 and col2.

The first error you got with pgx was because PostgreSQL returned a one column results set where you expected 12 columns.

See example below:

pgx_test=# insert into widgets (name, description, creation_time) values ('foo', 'bar', now()) returning (id, name, description);
      row      
───────────────
 (328,foo,bar)
(1 row)

INSERT 0 1
Time: 7.974 ms
pgx_test=# insert into widgets (name, description, creation_time) values ('foo', 'bar', now()) returning id, name, description;
 id  β”‚ name β”‚ description 
─────┼──────┼─────────────
 329 β”‚ foo  β”‚ bar
(1 row)

INSERT 0 1
Time: 7.542 ms

Thanks for the explanation @jackc I did figure it out. That's why I've written the 2nd post.
Maybe it wasn't clear enough but, you probably don't want to support the 2nd case right?

Well, it is supported, though I'm not sure when it would make sense to actually use it that way. You can scan into a single pgtype.Record struct.

You could do something like:

var row pgtype.Record
err := conn.QueryRow("insert ... returning (...)").Scan(&row)

There are a few limitation though. First, due to how PostgreSQL represents record types it will only work using the binary format. This is what pgx uses by default but if you were also forcing the text format for some reason (e.g. to reduce round trips to PG server) then row types are not readable. Secondly, you lose the names of the columns and have to access the data positionally. Third, you lose the ability to scan the record fields into specific or custom types.

So you _can_ do it, but I think it would only make sense in rare circumstances.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nick-jones picture nick-jones  Β·  4Comments

jeromer picture jeromer  Β·  11Comments

hgl picture hgl  Β·  6Comments

zargex picture zargex  Β·  8Comments

mrdulin picture mrdulin  Β·  4Comments