Received: from maia.hub.org (maia-3.hub.org [200.46.204.243]) by mail.postgresql.org (Postfix) with ESMTP id 4F66DB5DD01 for ; Sat, 17 Sep 2011 11:53:03 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.243]) (amavisd-maia, port 10024) with ESMTP id 74137-03-5 for ; Sat, 17 Sep 2011 14:52:56 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.8.0-rc2 Received: from mailout-de.gmx.net (mailout-de.gmx.net [213.165.64.23]) by mail.postgresql.org (Postfix) with SMTP id BCE38B5DC68 for ; Sat, 17 Sep 2011 11:52:51 -0300 (ADT) Received: (qmail invoked by alias); 17 Sep 2011 14:52:48 -0000 Received: from mue-88-130-44-087.dsl.tropolys.de (EHLO [192.168.1.113]) [88.130.44.87] by mail.gmx.net (mp007) with SMTP; 17 Sep 2011 16:52:48 +0200 X-Authenticated: #14269776 X-Provags-ID: V01U2FsdGVkX18mo8oBH5km13jrRzGfWa8DqeQpAKNbCm1fzTNvgS BZPHhy120iQrjw Message-ID: <4E74B447.1080509@gmx.net> Date: Sat, 17 Sep 2011 16:52:55 +0200 From: Andreas User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20110902 Thunderbird/6.0.2 MIME-Version: 1.0 To: pgsql-sql@postgresql.org Subject: insert or update within transaction Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Y-GMX-Trusted: 0 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-2.393 tagged_above=-5 required=5 tests=BAYES_00=-1.9, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RP_MATCHES_RCVD=-0.504, T_TO_NO_BRKTS_FREEMAIL=0.01 X-Spam-Level: X-Archive-Number: 201109/41 X-Sequence-Number: 35841 Hi, http://www.postgresql.org/docs/current/static/sql-update.html has an example where an either an insert or update is done according if a key already exists. The example is about wines. I did it with numbers. drop table if exists tbl; create table tbl ( key int primary key, val int ); insert into tbl ( key, val ) values ( 1, 1 ), ( 2, 2 ), ( 3, 3 ), ( 8, 8 ); So the key 8 exists. Now I issue the commands according to the example in the docu: BEGIN; -- other operations SAVEPOINT sp1; INSERT INTO tbl VALUES( 8, 15 ); -- Assume the above fails because of a unique key violation, -- so now we issue these commands: ROLLBACK TO sp1; UPDATE tbl SET val = 15 WHERE key = 8; -- continue with other operations, and eventually COMMIT; Instead of the update the query fails with an double key value error for the primary key. Shouldn't the insert fail, get rolled back and then exercute an update instead successfully? Now if this actually worked would be nice but is there a more general statement that does an insert if the key doesn't exist or an update if it allready is there? As I understand if the example above worked, it rolled back the insert in any case and so it is actually equivalent to the update anyway. If the key 8 doesnt't exist the example does actually nothing to the table.