dbTalk Databases Forums  

Last value inserted

comp.databases.postgresql.general comp.databases.postgresql.general


Discuss Last value inserted in the comp.databases.postgresql.general forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
MaRCeLO PeReiRA
 
Posts: n/a

Default Last value inserted - 11-11-2004 , 06:59 AM






Hi guys,

I am in troubles with a SERIAL field.

I have five tables. A parent table and four child
tables. When I do the INSERT in the parent table, I
have an ID (generated) by the sequence (SERIAL field),
and I have to use this ID to reference all child
tables.

Well, once I do an INSERT in the parent table, how can
I know (for sure) which number id was generated by the
sequence?

Simple example:

------------------------------------------------------
CREATE TABLE parent(id SERIAL, descrip CHAR(50));
------------------------------------------------------

So,

------------------------------------------------------
INSERT INTO parent (descrip) VALUES ('project 1');
------------------------------------------------------

How can I now (for sure) with value was generated by
the sequence to fill the field ID?

(There is lots of users using the software at the same
time, so I am not able to use the last_value()
function on the sequence.)

Best Regards,

Marcelo Pereira
Brazil





__________________________________________________ _____
Yahoo! Acesso Grátis - Internet rápida e grátis. Instale o discador agora! http://br.acesso.yahoo.com/

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster


Reply With Quote
  #2  
Old   
Uwe C. Schroeder
 
Posts: n/a

Default Re: Last value inserted - 11-11-2004 , 12:03 PM






-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


option 1) use a stored procedure to create the record. Within a transaction
the last value function will return the correct last value, not the one of a
concurrent insert.
option 2) if you know that this user uses the same connection for all his
queries - or at least the ones in question - you can rely on the last value
being the correct one. Like with transactions, if you use the same connection
the last value will be the correct one.

You're only in trouble if you're not within a transaction and you're not sure
if the connection stays the same for the queries in question. The later could
be due to connection pooling.

UC


On Thursday 11 November 2004 04:59 am, MaRCeLO PeReiRA wrote:
Quote:
Hi guys,

I am in troubles with a SERIAL field.

I have five tables. A parent table and four child
tables. When I do the INSERT in the parent table, I
have an ID (generated) by the sequence (SERIAL field),
and I have to use this ID to reference all child
tables.

Well, once I do an INSERT in the parent table, how can
I know (for sure) which number id was generated by the
sequence?

Simple example:

------------------------------------------------------
CREATE TABLE parent(id SERIAL, descrip CHAR(50));
------------------------------------------------------

So,

------------------------------------------------------
INSERT INTO parent (descrip) VALUES ('project 1');
------------------------------------------------------

How can I now (for sure) with value was generated by
the sequence to fill the field ID?

(There is lots of users using the software at the same
time, so I am not able to use the last_value()
function on the sequence.)

Best Regards,

Marcelo Pereira
Brazil





__________________________________________________ _____
Yahoo! Acesso Grátis - Internet rápida e grátis. Instale o discadoragora!
http://br.acesso.yahoo.com/

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD4DBQFBk6lnjqGXBvRToM4RAgOXAJiVy9TG9Yv05pegzACw2V PeN7USAKDRYg/N
H0BKK8WT1aOZ+CB3rCl8WQ==
=kiLq
-----END PGP SIGNATURE-----


---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match



Reply With Quote
  #3  
Old   
Bruno Wolff III
 
Posts: n/a

Default Re: Last value inserted - 11-11-2004 , 12:06 PM



On Thu, Nov 11, 2004 at 09:59:16 -0300,
MaRCeLO PeReiRA <gandalf_mp (AT) yahoo (DOT) com.br> wrote:
Quote:
Well, once I do an INSERT in the parent table, how can
I know (for sure) which number id was generated by the
sequence?
Use currval.

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org



Reply With Quote
  #4  
Old   
Robby Russell
 
Posts: n/a

Default Re: Last value inserted - 11-11-2004 , 12:13 PM



On Thu, 2004-11-11 at 09:59 -0300, MaRCeLO PeReiRA wrote:
Quote:
Hi guys,

I am in troubles with a SERIAL field.

I have five tables. A parent table and four child
tables. When I do the INSERT in the parent table, I
have an ID (generated) by the sequence (SERIAL field),
and I have to use this ID to reference all child
tables.

Well, once I do an INSERT in the parent table, how can
I know (for sure) which number id was generated by the
sequence?

Simple example:

------------------------------------------------------
CREATE TABLE parent(id SERIAL, descrip CHAR(50));
------------------------------------------------------

So,

------------------------------------------------------
INSERT INTO parent (descrip) VALUES ('project 1');
------------------------------------------------------

How can I now (for sure) with value was generated by
the sequence to fill the field ID?

(There is lots of users using the software at the same
time, so I am not able to use the last_value()
function on the sequence.)

Best Regards,

Marcelo Pereira
Brazil

I just asked this same question about a week or two ago and I got a
response from Jonathan Daugherty who helped me with the initial query,
and in PHP I was able to come up with:

http://blog.planetargon.com/index.ph...nsert_id_.html

This was on the list a few weeks ago:

Quote:
-- get_sequence(schema_name, table_name, column_name)

CREATE OR REPLACE FUNCTION get_sequence (text, text, text) RETURNS
text AS '
SELECT seq.relname::text
FROM pg_class src, pg_class seq, pg_namespace, pg_attribute,
pg_depend
WHERE
pg_depend.refobjsubid = pg_attribute.attnum AND
pg_depend.refobjid = src.oid AND
seq.oid = pg_depend.objid AND
src.relnamespace = pg_namespace.oid AND
pg_attribute.attrelid = src.oid AND
pg_namespace.nspname = $1 AND
src.relname = $2 AND
pg_attribute.attname = $3;
' language sql;
hth,

Robby

--
/***************************************
* Robby Russell | Owner.Developer.Geek
* PLANET ARGON | www.planetargon.com
* Portland, OR | robby (AT) planetargon (DOT) com
* 503.351.4730 | blog.planetargon.com
* PHP/PostgreSQL Hosting & Development
* --- Now supporting PHP5 ---
****************************************/

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQBBk6vN0QaQZBaqXgwRAiK0AJ9B6QPP/fjeHe4PoCqAFkssse6x4ACg3ad6
gEQQ4QsuSQ8UGXOKPKc+8+4=
=Xn7A
-----END PGP SIGNATURE-----



Reply With Quote
  #5  
Old   
Franco Bruno Borghesi
 
Posts: n/a

Default Re: Last value inserted - 11-11-2004 , 12:23 PM



I think the best way would be not to use a SERIAL field, but an INTEGER
field and a sequence:

CREATE SEQUENCE parent_seq;
CREATE TABLE parent(id INTEGER, descrip CHAR(50));


So when you want to insert on the parent table, you obtain the next
value from the sequence and then you insert in the parent and child
tables the value you obtained:

newId:=SELECT nextval('parent_seq')
INSERT INTO parent(id, descrip) VALUES (newId, 'XXXX');
INSERT INTO child_1(..., ..., parentId) VALUES (..., ..., newId);
INSERT INTO child_2(..., ..., parentId) VALUES (..., ..., newId);
INSERT INTO child_3(..., ..., parentId) VALUES (..., ..., newId);


hope it helps.

MaRCeLO PeReiRA wrote:

Quote:
Hi guys,

I am in troubles with a SERIAL field.

I have five tables. A parent table and four child
tables. When I do the INSERT in the parent table, I
have an ID (generated) by the sequence (SERIAL field),
and I have to use this ID to reference all child
tables.

Well, once I do an INSERT in the parent table, how can
I know (for sure) which number id was generated by the
sequence?

Simple example:

------------------------------------------------------
CREATE TABLE parent(id SERIAL, descrip CHAR(50));
------------------------------------------------------

So,

------------------------------------------------------
INSERT INTO parent (descrip) VALUES ('project 1');
------------------------------------------------------

How can I now (for sure) with value was generated by
the sequence to fill the field ID?

(There is lots of users using the software at the same
time, so I am not able to use the last_value()
function on the sequence.)

Best Regards,

Marcelo Pereira
Brazil





__________________________________________________ _____
Yahoo! Acesso Grátis - Internet rápida e grátis. Instale o discador agora! http://br.acesso.yahoo.com/

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster




---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
(send "unregister YourEmailAddressHere" to majordomo (AT) postgresql (DOT) org)



Reply With Quote
  #6  
Old   
Richard Huxton
 
Posts: n/a

Default Re: Last value inserted - 11-11-2004 , 12:44 PM



MaRCeLO PeReiRA wrote:

Quote:
How can I now (for sure) with value was generated by
the sequence to fill the field ID?

(There is lots of users using the software at the same
time, so I am not able to use the last_value()
function on the sequence.)
Yes you are nextval()/currval() are multi-user safe. They return the
next/current value *in the current connection*.

--
Richard Huxton
Archonet Ltd

---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend



Reply With Quote
  #7  
Old   
Jerry III
 
Posts: n/a

Default Re: Last value inserted - 11-11-2004 , 07:51 PM



Which means that sometimes they do not return the correct value - if you
have a trigger that inserts another record you will not get the right value.
MSSQL has @@IDENTITY and SCOPE_IDENTITY() to handle this case, I'm new to
pgsql so I don't know if it has anything like that.

Jerry

"Richard Huxton" <dev (AT) archonet (DOT) com> wrote

Quote:
MaRCeLO PeReiRA wrote:

How can I now (for sure) with value was generated by
the sequence to fill the field ID?

(There is lots of users using the software at the same
time, so I am not able to use the last_value()
function on the sequence.)

Yes you are nextval()/currval() are multi-user safe. They return the
next/current value *in the current connection*.

--
Richard Huxton
Archonet Ltd

---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend




Reply With Quote
  #8  
Old   
Uwe C. Schroeder
 
Posts: n/a

Default Re: Last value inserted - 11-11-2004 , 11:58 PM



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Thursday 11 November 2004 10:23 am, Franco Bruno Borghesi wrote:
Quote:
I think the best way would be not to use a SERIAL field, but an INTEGER
field and a sequence:
a "serial" is just a convenient shortcut to an int with an automatically
created sequence. As proof - just create a table with a serial and dump it
with pg_dump: you'll end up with a table containing an int with a nextval(....
as the default. The only difference is that in case of the "serial" field you
don't name the sequence yourself.

Quote:
CREATE SEQUENCE parent_seq;
CREATE TABLE parent(id INTEGER, descrip CHAR(50));


So when you want to insert on the parent table, you obtain the next
value from the sequence and then you insert in the parent and child
tables the value you obtained:

newId:=SELECT nextval('parent_seq')
INSERT INTO parent(id, descrip) VALUES (newId, 'XXXX');
INSERT INTO child_1(..., ..., parentId) VALUES (..., ..., newId);
INSERT INTO child_2(..., ..., parentId) VALUES (..., ..., newId);
INSERT INTO child_3(..., ..., parentId) VALUES (..., ..., newId);
which amounts to the curval in the same connection.

Quote:
hope it helps.

MaRCeLO PeReiRA wrote:
Hi guys,

I am in troubles with a SERIAL field.

I have five tables. A parent table and four child
tables. When I do the INSERT in the parent table, I
have an ID (generated) by the sequence (SERIAL field),
and I have to use this ID to reference all child
tables.

Well, once I do an INSERT in the parent table, how can
I know (for sure) which number id was generated by the
sequence?

Simple example:

------------------------------------------------------
CREATE TABLE parent(id SERIAL, descrip CHAR(50));
------------------------------------------------------

So,

------------------------------------------------------
INSERT INTO parent (descrip) VALUES ('project 1');
------------------------------------------------------

How can I now (for sure) with value was generated by
the sequence to fill the field ID?

(There is lots of users using the software at the same
time, so I am not able to use the last_value()
function on the sequence.)

Best Regards,

Marcelo Pereira
Brazil





__________________________________________________ _____
Yahoo! Acesso Grátis - Internet rápida e grátis. Instale o discador agora!
http://br.acesso.yahoo.com/

---------------------------(end of broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster

---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
(send "unregister YourEmailAddressHere" to majordomo (AT) postgresql (DOT) org)
- --
UC

- --
Open Source Solutions 4U, LLC 2570 Fleetwood Drive
Phone: +1 650 872 2425 San Bruno, CA 94066
Cell: +1 650 302 2405 United States
Fax: +1 650 872 2417
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQFBlFD5jqGXBvRToM4RAmfQAJ9JyQxERqcau1kCnvkrXN mpaGTwzwCgqK6L
7zCpR+uO5pzvDuY/itTYCfs=
=mq0M
-----END PGP SIGNATURE-----


---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo (AT) postgresql (DOT) org



Reply With Quote
  #9  
Old   
Jeff Eckermann
 
Posts: n/a

Default Re: Last value inserted - 11-16-2004 , 08:54 AM



--- Jerry III <jerryiii (AT) hotmail (DOT) com> wrote:

Quote:
Which means that sometimes they do not return the
correct value - if you
have a trigger that inserts another record you will
not get the right value.
If you are new to PostgreSQL, as you say, then why are
you so sure of this? Perhaps you may profit from
looking a little more at how currval() works.

Quote:
MSSQL has @@IDENTITY and SCOPE_IDENTITY() to handle
this case, I'm new to
pgsql so I don't know if it has anything like that.

Jerry

"Richard Huxton" <dev (AT) archonet (DOT) com> wrote in message

news:4193B30B.40905 (AT) archonet (DOT) com...
MaRCeLO PeReiRA wrote:

How can I now (for sure) with value was generated
by
the sequence to fill the field ID?

(There is lots of users using the software at the
same
time, so I am not able to use the last_value()
function on the sequence.)

Yes you are nextval()/currval() are multi-user
safe. They return the
next/current value *in the current connection*.

--
Richard Huxton
Archonet Ltd

---------------------------(end of
broadcast)---------------------------
TIP 8: explain analyze is your friend




---------------------------(end of
broadcast)---------------------------
TIP 4: Don't 'kill -9' the postmaster




__________________________________
Do you Yahoo!?
The all-new My Yahoo! - Get yours free!
http://my.yahoo.com



---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings



Reply With Quote
  #10  
Old   
Stephan Szabo
 
Posts: n/a

Default Re: Last value inserted - 11-16-2004 , 09:47 AM




On Tue, 16 Nov 2004, Jeff Eckermann wrote:

Quote:
--- Jerry III <jerryiii (AT) hotmail (DOT) com> wrote:

Which means that sometimes they do not return the
correct value - if you
have a trigger that inserts another record you will
not get the right value.

If you are new to PostgreSQL, as you say, then why are
you so sure of this? Perhaps you may profit from
looking a little more at how currval() works.
He's correct. One thing that currval will not help with is a
case where more than one row has been inserted by a statement
(whether due to the base statement or triggers).

A somewhat absurd example:

---

create table q1(a serial, b int);

create function f1() returns trigger as 'begin if (random() >
0.5) then insert into q1 default values; end if; return NEW; end;'
language 'plpgsql';

create trigger q1_f1 after insert on q1 for each row execute
procedure f1();

insert into q1(b) values (3);

select currval('q1_a_seq');

select * from q1;

----

I got a currval of 3 which was the last row inserted, but that was from
the trigger, not the row created by my insert so it didn't have the
correct b value.

---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match



Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.