tags:

views:

30

answers:

2

This is how I do this in sql server.

insert into users(name) values('jhon');
set @id = @@identity; -- last serial

insert into usersroles(@id, 1)
insert into usersroles(@id, 2)
insert into usersroles(@id, 3)

How can I do the same in postgres (withouth creating a function)?

+2  A: 
CREATE TABLE users (id SERIAL NOT NULL, name TEXT);
CREATE TABLE userroles (user_id INT NOT NULL, role_id INT NOT NULL);

INSERT
INTO    users (name)
VALUES  ('John');

INSERT
INTO    userroles (user_id, role_id)
VALUES  (CURRVAL('users_id_seq'), 1),
        (CURRVAL('users_id_seq'), 2),
        (CURRVAL('users_id_seq'), 3);
Quassnoi
cool, but is there any other way like using declare or that's only inside plpgsql functions ?
Omu
@Omu: `DECLARE` is only within `PL/PGSQL`. You can use unholy magic with `custom_variable_classes` to set session variables, but I wouldn't recommend this. Actually, what's bad in the `CURRVAL` solution?
Quassnoi
@Quassnoi nothing, it's just my first day with postgres and I'm used with the sql server stuff
Omu
Is `CURRVAL` concurrency safe? Meaning, if another query called `NEXTVAL('users_id_seq')` between the INSERTS --wouldn't CURRVAL reflect the latest value and not the intended one?
OMG Ponies
@OMG Ponies it looks like so http://www.postgresql.org/docs/9.0/static/functions-sequence.html "Return the value most recently obtained by nextval for this sequence in the current session"
Omu
@Omu: That minimizes the window of opportunity, but it doesn't specify if the transaction is respected.
OMG Ponies
@OMGPonies: `CURRVAL` is implemented as a session variable. The queries called from another sessions do not affect `CURRVAL`. You have full control of the queries within your own session. This means that if you don't increment the sequence within your session, `CURRVAL` persists, even if another query in another session messes with the sequence. It's similar to `SCOPE_IDENTITY` in `SQL Server`.
Quassnoi
A: 

Additionally you can use the keyword DEFAULT to specify the default value for the column. And the Postgres extension RETURNING to return the id that was just inserted.

INSERT INTO users (id, name) VALUES (default, 'Bob') RETURNING id;
Scott Bailey
@Scott: how do you insert the returned value into another table without storing it into a variable first?
Quassnoi
You don't. The point of using returning is to stuff it in a variable. If you don't want to use variables then you'll need to use currval()
Scott Bailey