pg.ddx.io  pgsql-sql@postgresql.org mailing list archive  
help / color / mirror / Atom feed
transaction
5+ messages / 4 participants
[nested] [flat]

* transaction
@ 2004-04-20 19:14  H.J. Sanders <hjs@worldonline.nl>
  0 siblings, 2 replies; 5+ messages in thread

From: H.J. Sanders @ 2004-04-20 19:14 UTC (permalink / raw)
  To: pgsql-sql


Hello list.

We are migrating from Informix to PSQL.

In Informix we used to do:

- BEGIN WORK

- INSERT ROW

- IF FAILED THEN UPDATE ROW

- COMMIT WORK


In PSQL  this does not seem to work because after the first error (the
insert)
everything is omitted.

Has someone found a solution for this (we have 1000's of this type).

Henk Sanders











^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: transaction
@ 2004-04-21 02:00  Bruno Wolff III <bruno@wolff.to>
  parent: H.J. Sanders <hjs@worldonline.nl>
  1 sibling, 1 reply; 5+ messages in thread

From: Bruno Wolff III @ 2004-04-21 02:00 UTC (permalink / raw)
  To: H.J. Sanders <hjs@worldonline.nl>; +Cc: pgsql-sql

On Tue, Apr 20, 2004 at 21:14:48 +0200,
  "H.J. Sanders" <hjs@worldonline.nl> wrote:
> 
> Hello list.
> 
> We are migrating from Informix to PSQL.
> 
> In Informix we used to do:
> 
> - BEGIN WORK
> 
> - INSERT ROW
> 
> - IF FAILED THEN UPDATE ROW
> 
> - COMMIT WORK
> 
> 
> In PSQL  this does not seem to work because after the first error (the
> insert)
> everything is omitted.
> 
> Has someone found a solution for this (we have 1000's of this type).

This question has come up a few times over the last year and there isn't
a great answer. Locking the table is a simple solution, but can lead to
problems because of contention.



^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: transaction
@ 2004-04-21 07:28  denis@coralindia.com
  parent: Bruno Wolff III <bruno@wolff.to>
  0 siblings, 1 reply; 5+ messages in thread

From: denis@coralindia.com @ 2004-04-21 07:28 UTC (permalink / raw)
  To: Bruno Wolff III <bruno@wolff.to>; H.J. Sanders <hjs@worldonline.nl>; +Cc: pgsql-sql


Hi,

You can achieve this by:

1. Create a new table
2. Insert the data in this.
3. Write a trigger on this table
4. In trigger issue UPDATE and check whether it updated any records. If NO,
fire INSERT.
    ( here, i am updating first and inserting.. just reverse )

The code looks like:

        update tempxitag set qty = qty + nqty where
                ccod = cccod
        GET DIAGNOSTICS nFound = ROW_COUNT;
        If nFound = 0 then
            insert into tempxitag( ccod, qty)
            values (cccod, nqty );
        End if;

HTH

Denis


----- Original Message -----
From: Bruno Wolff III <bruno@wolff.to>
To: H.J. Sanders <hjs@worldonline.nl>
Cc: <pgsql-sql@postgresql.org>
Sent: Wednesday, April 21, 2004 7:30 AM
Subject: Re: [SQL] transaction


> On Tue, Apr 20, 2004 at 21:14:48 +0200,
>   "H.J. Sanders" <hjs@worldonline.nl> wrote:
> >
> > Hello list.
> >
> > We are migrating from Informix to PSQL.
> >
> > In Informix we used to do:
> >
> > - BEGIN WORK
> >
> > - INSERT ROW
> >
> > - IF FAILED THEN UPDATE ROW
> >
> > - COMMIT WORK
> >
> >
> > In PSQL  this does not seem to work because after the first error (the
> > insert)
> > everything is omitted.
> >
> > Has someone found a solution for this (we have 1000's of this type).
>
> This question has come up a few times over the last year and there isn't
> a great answer. Locking the table is a simple solution, but can lead to
> problems because of contention.
>
> ---------------------------(end of broadcast)---------------------------
> TIP 7: don't forget to increase your free space map settings





^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: transaction
@ 2004-04-21 10:13  Andrew Sullivan <ajs@crankycanuck.ca>
  parent: H.J. Sanders <hjs@worldonline.nl>
  1 sibling, 0 replies; 5+ messages in thread

From: Andrew Sullivan @ 2004-04-21 10:13 UTC (permalink / raw)
  To: pgsql-sql

On Tue, Apr 20, 2004 at 09:14:48PM +0200, H.J. Sanders wrote:
> 
> - BEGIN WORK
> 
> - INSERT ROW
> 
> - IF FAILED THEN UPDATE ROW
> 
> - COMMIT WORK

You can do it the other way.  Begin, update; if 0 rows are updated
then insert.

A
-- 
Andrew Sullivan  | ajs@crankycanuck.ca



^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: transaction
@ 2004-04-21 18:02  Bruno Wolff III <bruno@wolff.to>
  parent: denis@coralindia.com
  0 siblings, 0 replies; 5+ messages in thread

From: Bruno Wolff III @ 2004-04-21 18:02 UTC (permalink / raw)
  To: denis@coralindia.com; +Cc: H.J. Sanders <hjs@worldonline.nl>; pgsql-sql

On Wed, Apr 21, 2004 at 12:58:56 +0530,
  denis@coralindia.com wrote:
> 
> The code looks like:
> 
>         update tempxitag set qty = qty + nqty where
>                 ccod = cccod
>         GET DIAGNOSTICS nFound = ROW_COUNT;
>         If nFound = 0 then
>             insert into tempxitag( ccod, qty)
>             values (cccod, nqty );
>         End if;

You still can get errors if two transactions try to refer to the same
nonexistant record at the same time. Postgres doesn't do predicate
locking so the update won't lock the to be inserted row and both
transactions may see the record as not existing and both try to do
an insert.

Updating, checking the count and then trying an insert if the count was
0 and retrying if the insert fails may be a better approach than locking
the table. However, since this is an existing application it may be hard
to make this complicated of a change.

If there is flexibility in how the task gets done, switching to something
based on sequences is probably the way to go.



^ permalink  raw  reply  [nested|flat] 5+ messages in thread


end of thread, other threads:[~2004-04-21 18:02 UTC | newest]

Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2004-04-20 19:14 transaction H.J. Sanders <hjs@worldonline.nl>
2004-04-21 02:00 ` Bruno Wolff III <bruno@wolff.to>
2004-04-21 07:28   ` denis@coralindia.com
2004-04-21 18:02     ` Bruno Wolff III <bruno@wolff.to>
2004-04-21 10:13 ` Andrew Sullivan <ajs@crankycanuck.ca>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox