From: | Merlin Moncure <mmoncure(at)gmail(dot)com> |
---|---|
To: | Ross Boylan <ross(at)biostat(dot)ucsf(dot)edu> |
Cc: | pgsql-novice(at)postgresql(dot)org |
Subject: | Re: coalesce in plpgsql, and other style questions |
Date: | 2012-06-13 14:02:22 |
Message-ID: | CAHyXU0wZRQ4psAAY5OPGkDqkdJYMMHguXJrzPn0T83KFrCvHSg@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-novice |
On Tue, Jun 12, 2012 at 12:46 PM, Ross Boylan <ross(at)biostat(dot)ucsf(dot)edu> wrote:
> I just wrote my first pl/pgsql function, and would appreciate any
> comments people have on it. I'll be writing a bunch of similar
> functions, with semantics "give me the id of the object if exists,
> otherwise create it and give me the id."
>
> My solution seems excessively procedural to me. I thought I could get
> the right semantics with something like
> select coalesce((select id from mytable where name='foo'),
> (insert into mytable ('name') values('foo') returning id))
> but I could not get that to work in plgsql.
for posterity:
with a as (select id from mytable where name='foo'),
b as
(
insert into mytable (name)
select 'foo' where not exists (select 1 from a)
returning id
)
select * from a union all select * from b;
I definitely appreciate the desire to avoid procedural implementations
of things like this. Just be advised that this is a postgresql-ism
(data modifying 'with' is not standard syntax). This also (as Jeff
notes) has no bearing on the race to the id: you must be prepared to
retry the above statement in face of concurrent attempts to insert to
the same unique value unless you have taken a lock to guard against
this. I don't think it's possible to work that lock into the CTE.
merlin
From | Date | Subject | |
---|---|---|---|
Next Message | Ross Boylan | 2012-06-13 18:34:25 | Re: coalesce in plpgsql, and other style questions |
Previous Message | Daniel Staal | 2012-06-13 13:52:03 | Re: coalesce in plpgsql, and other style questions |