Received: from localhost (maia-1.hub.org [200.46.204.191]) by postgresql.org (Postfix) with ESMTP id 38D8F9FB8DF for ; Thu, 19 Apr 2007 15:59:07 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.191]) (amavisd-maia, port 10024) with ESMTP id 35006-07 for ; Thu, 19 Apr 2007 15:59:00 -0300 (ADT) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.4 Received: from an-out-0708.google.com (an-out-0708.google.com [209.85.132.248]) by postgresql.org (Postfix) with ESMTP id DF8DD9FB43A for ; Thu, 19 Apr 2007 15:59:00 -0300 (ADT) Received: by an-out-0708.google.com with SMTP id c24so634130ana for ; Thu, 19 Apr 2007 11:59:00 -0700 (PDT) DKIM-Signature: a=rsa-sha1; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=ACwZtrDF4+0ojhGlDZ0S87l30GL057jXjcjh9atItRcw68J1eM4EEHNYsHBdZcZwYrdlxlzmefs+mIb8HXTRIAkp29A8OUPxC7w1PTbJ0np61r/zgYelUzKn8yp1w9GBWJQAVGWbIemD1hlnHixHKGtOcFaXYu9DBhlARmYNQCw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=VxBA4UqXbl7VHJJfg5pQc8QpVQz4GPoI16Pfbo1breqgeO4xXVJ8oe+ObYXHcmBB0pFIUs3iD5W5GQxzSulKL4Y7/AUlOkLO/wDqbVfT1SlTPIZVn+US8661OWVLak6/0J54+J+ICu1yPVCLgzK3IpRmr0f4YsqNUGvlhuhardc= Received: by 10.100.43.9 with SMTP id q9mr1116961anq.1177009139783; Thu, 19 Apr 2007 11:58:59 -0700 (PDT) Received: by 10.100.154.9 with HTTP; Thu, 19 Apr 2007 11:58:59 -0700 (PDT) Message-ID: Date: Thu, 19 Apr 2007 13:58:59 -0500 From: "=?ISO-8859-1?Q?Rodrigo_De_Le=F3n?=" To: pgsql-sql@postgresql.org Subject: Re: Doing a conditional insert/update Cc: "Markus Holzer" In-Reply-To: <978075550704191127g781a4a26i400f4fc80d491df6@mail.gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <978075550704191127g781a4a26i400f4fc80d491df6@mail.gmail.com> X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200704/168 X-Sequence-Number: 28168 On 4/19/07, Markus Holzer wrote: > Hello. > > I'm currently developing my first web app with Postgres and I have a > question. > > How do I perform a conditional insert/update? > > To clarify: I need to insert data into a table when the primary key is not > already in the table, or an update if it is. I have currently solved this by > SELECTing for the primary key, then looking if there is a row, and if there > is I do an UPDATE otherwise I do an INSERT. But since this is a web app this > way of course leaves a big race condition. > > Is there a way to get around that? Like the ON DUPLICATE KEY UPDATE > statement in MySQL? > > > Thanks for your time, > > Holli -------------------------------------------------- CREATE TABLE db (a INT PRIMARY KEY, b TEXT); CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS $$ BEGIN LOOP UPDATE db SET b = data WHERE a = key; IF found THEN RETURN; END IF; BEGIN INSERT INTO db(a,b) VALUES (key, data); RETURN; EXCEPTION WHEN unique_violation THEN -- do nothing END; END LOOP; END; $$ LANGUAGE plpgsql; SELECT merge_db(1, 'david'); SELECT merge_db(1, 'dennis'); -------------------------------------------------- Straight from the docs: http://www.postgresql.org/docs/8.2/static/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING