X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (av.hub.org [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id 68628D6F13 for ; Tue, 25 Oct 2005 05:07:43 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 33265-10 for ; Tue, 25 Oct 2005 08:07:39 +0000 (GMT) Received: from boutiquenumerique.com (boutiquenumerique.com [82.67.9.10]) by svr1.postgresql.org (Postfix) with ESMTP id F2654D6EE1 for ; Tue, 25 Oct 2005 05:07:39 -0300 (ADT) Received: (qmail 21199 invoked from network); 25 Oct 2005 10:08:50 +0200 Received: from unknown (HELO localhost) (boutiquenumerique-lists@192.168.0.4) by boutiquenumerique.com with SMTP; 25 Oct 2005 10:08:50 +0200 To: tobbe , pgsql-sql@postgresql.org Subject: Re: automatic update or insert References: <1129790184.351579.302550@g47g2000cwa.googlegroups.com> Message-ID: Date: Tue, 25 Oct 2005 10:07:39 +0200 From: PFC Organization: =?iso-8859-15?Q?La_Boutique_Num=E9rique?= Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit In-Reply-To: <1129790184.351579.302550@g47g2000cwa.googlegroups.com> User-Agent: Opera M2/8.0 (Linux, build 1095) X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.006 required=5 tests=[AWL=0.006] X-Spam-Level: X-Archive-Number: 200510/281 X-Sequence-Number: 23134 > In a system of mine i need to insert records into table [tbStat], and > if the records exist i need to update them instead and increase a > column [cQuantity] for every update. > > I.e. the first insert sets cQuantity to 1, and for every other run > cQuantity is increased. > > Currently i have implemented this as a stored procedure in the plpgsql > language. This means that in my stored procedure i first do a select to > find out if the row exists or not, then i do a insert or update > depending if the row existed. There are two ways you can do this : * If you will have more updates than inserts (ie. more items with a quantity >1 than 1) : UPDATE If the update updated no rows, then INSERT * If you have more inserts than updates (ie. more items with quantity 1 than >1) : INSERT if it fails due to violating the unique constraint, then UPDATE None of these involve a SELECT. The first one is very cheap if you end up doing more updates than inserts, because it just does the update. You will of course need a UNIQUE index to identify your rows, and prevent insertion of duplicates. I suppose you have this already. There is a subtility in the second form : the INSERT will fail on duplicate key, so you have to either rollback the transaction if you send the queries raw from your app, or catch the exception in your plpgsql function. Also a race condition might exist if someone deletes a row in-between, or the first procedure is executed twice at the same time by different threads. Be prepared to retry your transaction. Something like the ON DUPLICATE KEY UPDATE in MySQL would be nice to have.