X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id DF82C53430 for ; Tue, 29 Mar 2005 11:13:01 +0100 (BST) 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 82577-10 for ; Tue, 29 Mar 2005 10:12:57 +0000 (GMT) Received: from anchor-post-31.mail.demon.net (anchor-post-31.mail.demon.net [194.217.242.89]) by svr1.postgresql.org (Postfix) with ESMTP id 3CA5B53464 for ; Tue, 29 Mar 2005 11:12:55 +0100 (BST) Received: from mwynhau.demon.co.uk ([193.237.186.96] helo=mainbox.archonet.com) by anchor-post-31.mail.demon.net with esmtp (Exim 4.42) id 1DGDg1-000OdH-3l; Tue, 29 Mar 2005 10:10:29 +0000 Received: from [192.168.1.17] (client17.archonet.com [192.168.1.17]) by mainbox.archonet.com (Postfix) with ESMTP id 73982172C7; Tue, 29 Mar 2005 11:12:45 +0100 (BST) Message-ID: <42492A1D.9060404@archonet.com> Date: Tue, 29 Mar 2005 11:12:45 +0100 From: Richard Huxton User-Agent: Mozilla Thunderbird 1.0 (X11/20041206) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Andrus Moor Cc: pgsql-sql@postgresql.org Subject: Re: Merging item codes using referential integrity References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.06 tagged_above=0 required=5 tests=AWL, FORGED_RCVD_HELO X-Spam-Level: X-Archive-Number: 200503/372 X-Sequence-Number: 20851 Andrus Moor wrote: > I have item table and a lot of child tables where the items are used. > I want to merge two item codes into single item in all tables. > It is not nice to write a lot of separate UPDATE statements for each table. > So I want to utilize REFERENCES clause for merging. > > I tried the following code but got duplicate key error in UPDATE > statement. > > Any idea how to impement this? > > CREATE TABLE parent ( code CHAR(10) PRIMARY KEY ); > BEGIN; > -- Direct Postgres to update all child tables. This causes error. > UPDATE parent SET code='1' WHERE code='2'; > -- Remove duplicate row That's the problem - you can't have a duplicate row at *any* time with a primary key. The UNIQUE constraint is instant and can't be deferred (at least, not yet). However, in this case I would simply write a function: CREATE FUNCTION merge_all(char(10), char(10) AS ' UPDATE table_1 SET col_1=$2 WHERE col1=$1; UPDATE table_2 SET col_2=$2 WHERE col2=$2; ...etc... ' LANGUAGE SQL; Then: SELECT merge_all('OLD_VAL','NEW_VAL') for each value (you could even join to your "parent" table if all the values are in there). All the updates in the function take place in the same transaction, so if there are any problems then all changes will be rolled back. -- Richard Huxton Archonet Ltd