Received: from localhost (unknown [200.46.204.191]) by postgresql.org (Postfix) with ESMTP id 88F142E2D41 for ; Tue, 15 Jan 2008 16:20:25 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.191]) (amavisd-maia, port 10024) with ESMTP id 75804-05 for ; Tue, 15 Jan 2008 16:20:21 -0400 (AST) Received: from ro-out-1112.google.com (ro-out-1112.google.com [72.14.202.181]) by postgresql.org (Postfix) with ESMTP id 600E42E2D71 for ; Tue, 15 Jan 2008 16:20:21 -0400 (AST) Received: by ro-out-1112.google.com with SMTP id p4so3265534roc.5 for ; Tue, 15 Jan 2008 12:20:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; 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; bh=U63cCJmWGcNxfLXN4HC6uSz8rAvVPsdOboogAmZUpqI=; b=d3Up60wztDe/TY88ZwxXNSo3pde3RLbrcGenctP7bOzUvQN4sA2coqrjwkNrlZN97x3PeHBYxagDqjIBqpcbzu8MwiWLCduWzMmF3J2lxib0Pw3cuqOvyJl3PYPLK4fDiavWEvzB91QV1zEhVxmVDZu7j8RKqC03SReQKdMfKnc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:content-transfer-encoding:content-disposition:references; b=Fo/mgvgbFkMytdI6tWtYAZ7en6GC92M80/rQH7CPj7FUIbiW+5ND+frteNM8sptCfcPdGvda1zwEs0goWdnYx2hFwFfx/2HSjf1rutcQe4aiItdOaUH1Pu1giYwheSwv/NDSydkFhT1abT7ZS+tJ2RBAVczEEgFfTBW7Kz+6Bjk= Received: by 10.115.89.1 with SMTP id r1mr3095610wal.8.1200428419710; Tue, 15 Jan 2008 12:20:19 -0800 (PST) Received: by 10.114.131.4 with HTTP; Tue, 15 Jan 2008 12:20:19 -0800 (PST) Message-ID: Date: Tue, 15 Jan 2008 14:20:19 -0600 From: "Scott Marlowe" To: "Franklin Haut" Subject: Re: Update PK Violation Cc: pgsql-sql@postgresql.org In-Reply-To: <478D1FB5.2070003@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline References: <478D1FB5.2070003@gmail.com> X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200801/135 X-Sequence-Number: 29988 On Jan 15, 2008 3:03 PM, Franklin Haut wrote: > Hi all, > > i have a problem with one update sentence sql. > > example to produce: > > create table temp (num integer primary key, name varchar(20)); > > insert into temp values (1, 'THE'); > insert into temp values (2, 'BOOK'); > insert into temp values (3, 'IS'); > insert into temp values (4, 'ON'); > insert into temp values (5, 'THE'); > insert into temp values (6, 'RED'); > insert into temp values (7, 'TABLE'); > > -- now i need insert new row at position 4, for this i need increase the > field 'num' 4 to 5, 5 to 6, 6 to 7 and 7 to 8 > update temp set num =3D num + 1 where num > 5; > -- but this give an key violation error, because the postgresql try > change row 4 to 5 and the 5 exist. > --- the big question is... have one way to the command (update temp SNIP > set num =3D num + 1 where num > 5;) works ? > -- consideration, i can=B4t delete the primary key > -- using PG 8.2 / Windows Normally, I'd say you're doing it wrong, as PKs aren't supposed to change all the time. You're using this as a uniquer sequencer number, not a real PK. However, there are a few different work-arounds you might be able to implement, depending on your needs. 1: Drop the unique index in a transaction, put it back before you're done. This method has some serious locking issues you might run into, but if you only have one or two processes accessing your data, and it all happens in a quick succession, it should be safe. Since, if something in your activity fails, the transaction rolls back and your original unique index is still there. begin; drop index abc_pk_dx; update table set id =3D id + 1 where id > 5; create index unique abc_pk_dx on table (id); commit; 2: Put gaps in your sequence. Since you're not likely to have billions of billions of words, you can put gaps in your id sequence. I.e. 0, 20, 40, 60, 80, 100, so on. Add a word in the middle just give it a number like 50. If you run out of space, then lock the table and spread it out again. Shouldn't be necessary very often, if ever. If you need unlimited space between each, then switch to numeric. 3: Use an id to numeric lookup table. I.e. have a table hanging off to the side that has the REAL sequence numbers, and don't ever change them in the original table, but have another column there (or in the side table) that connects them to each other. Hope one of those ideas helps.