Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgres not returning lastval() properly

I am trying to insert a new user into our database, via psql in the CLI. When I do the following:

START TRANSACTION;
INSERT INTO "users" ("email", "first_name", "last_name", "password", "objectstate_id", "activate_rid")
VALUES ('[email protected]', 'Xpress', 'Care', 'f9fecdd84ee071806423adf30d6d6ff04e1a0a2c6688f2c057ddbab1d6b55d02', 4, 'EMQHTMMvViAB5BdYj0E6');
SELECT LASTVAL();

LASTVAL always returns 39037, which should technically be 838. It is also not inserting it into the DB for some reason. I have googled and looked for everything that I can think of and am not getting any answers. Does anyone have any idea what is going on here?

like image 375
benniemosher Avatar asked Jul 23 '13 19:07

benniemosher


People also ask

What is Setval in PostgreSQL?

The result returned by setval is just the value of its second argument. This function requires UPDATE privilege on the sequence. Returns the value most recently obtained by nextval for this sequence in the current session. (An error is reported if nextval has never been called for this sequence in this session.)

What is nextval in PostgreSQL?

NEXTVAL is a function to get the next value from a sequence. Sequence is an object which returns ever-increasing numbers, different for each call, regardless of transactions etc. Each time you call NEXTVAL , you get a different number. This is mainly used to generate surrogate primary keys for you tables.


1 Answers

The short version here is that using unqualified lastval is a bad idea. Triggers, rules, etc can cause problems.

You should avoid lastval entirely. Use:

BEGIN;

INSERT INTO "users" ("email", "first_name", "last_name", "password", "objectstate_id", "activate_rid") 
VALUES ('[email protected]', 'Xpress', 'Care', 'f9fecdd84ee071806423adf30d6d6ff04e1a0a2c6688f2c057ddbab1d6b55d02', 4, 'EMQHTMMvViAB5BdYj0E6') 
RETURNING id;

where id should by the name of the generated key column.

This approach will handle multi-valued inserts and INSERT INTO ... SELECT ... correctly, and won't have issues with triggers touching sequences.

If you must use a function-call based approach, at least use currval('tablename_id_seq') (passing the appropriate sequence name) instead of lastval.

like image 108
Craig Ringer Avatar answered Sep 28 '22 18:09

Craig Ringer