Received: from localhost (unknown [200.46.208.211]) by mail.postgresql.org (Postfix) with ESMTP id BE061633314 for ; Fri, 10 Apr 2009 11:40:53 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by localhost (mx1.hub.org [200.46.208.211]) (amavisd-maia, port 10024) with ESMTP id 38725-09 for ; Fri, 10 Apr 2009 11:40:42 -0300 (ADT) X-Greylist: delayed 00:08:31.882279 by SQLgrey-1.7.6 Received: from oberon.wxnz.net (oberon.wxnz.net [58.28.6.13]) by mail.postgresql.org (Postfix) with ESMTP id DA4F4632FD0 for ; Fri, 10 Apr 2009 11:40:51 -0300 (ADT) Received: from gonzo (ip-118-90-138-193.xdsl.xnet.co.nz [118.90.138.193]) by oberon.wxnz.net (Postfix) with ESMTP id 9C88A46586F for ; Sat, 11 Apr 2009 02:32:15 +1200 (NZST) Received: from news by gonzo with local (Exim 4.69) (envelope-from ) id 1LsHmA-00018u-FW for pgsql-sql@postgresql.org; Sat, 11 Apr 2009 02:32:14 +1200 To: pgsql-sql@postgresql.org Path: not-for-mail From: Jasen Betts Newsgroups: gmane.comp.db.postgresql.sql Subject: Re: changing multiple pk's in one update Date: 10 Apr 2009 14:32:14 GMT Organization: Dis (not Dat) Organisation Lines: 46 Message-ID: References: <49DC1034.1060705@frii.com> NNTP-Posting-Host: localhost Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: reversiblemaps.ath.cx 1239373934 4394 127.0.0.1 (10 Apr 2009 14:32:14 GMT) X-Face: ?)Aw4rXwN5u0~$nqKj`xPz>xHCwgi^q+^?Ri*+R(&uv2=E1Q0Zk(>h!~o2ID@6{uf8s; a +M[5[U[QT7xFN%^gR"=tuJw%TXXR'Fp~W; (T"1(739R%m0Yyyv*gkGoPA.$b,D.w:z+<'"=-lVT?6 {T?=R^:W5g|E2#EhjKCa+nt":4b}dU7GYB*HBxn&Td$@f%.kl^:7X8rQWd[NTc"P"u6nkisze/Q; 8 "9Z{peQF,w)7UjV$c|RO/mQW/NMgWfr5*$-Z%u46"/00mx-,\R'fLPe.)^ User-Agent: slrn/pre1.0.0-2 (Linux) X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200904/50 X-Sequence-Number: 32396 On 2009-04-08, Stuart McGraw wrote: > Hello all, > > I have a table with a primary key column > that contains sequential numbers. > > Sometimes I need to shift them all up or down > by a fixed amount. For example, if I have > four rows with primary keys, 2, 3, 4, 5, I > might want to shift them down by 1 by doing: > > UPDATE mytable SET id=id-1 > > (where "id" is the pk column) so that the pk's > are now 1, 2, 3, 4. > > When I try to shift them up by using +1 in the > above update statement, I get (not surprisingly) > a duplicate key error. I also realize that the > -1 case above works only by luck. > > So my question: > Is there some way, perhaps with ORDER BY, that > I can achieve the change I want with a single > update statement? (If I have an unused key > range large enough, I suppose I could update > all the keys to that range, and then back to > my target range but the requires two updates > (there are a lot of foreign keys referencing > these primary keys) and requires that I have > an available range, so a single update statement > would be preferable.) > > Thanks for any enlightenment. begin a transaction suspend the constraint (use SET CONSTRAINTS ... DEFERRED) drop the index do the update(s) recreate the index commit the transaction. I see no reason to keep the index (and its associated UNIQUE constraint) during the update, AFAICT all it does is slow the process down.