I have a table named employees which has 3 columns ( id , firstname, lastname) which already has 20 records . I want to insert a new record with the id=15 and shift the existing rows with id > 14 without replacing the existing record with id=15.
i tried to move the rows like following but that did not work
UPDATE employees
SET id = id + 1
WHERE id >= 15;
INSERT INTO employees (id , firstname, lastname)
VALUES (15, 'john', 'doe' );
UPDATE, NOTE : the id is used as a foreign key in another table called product, so if we modify the id’s in the employees table we have to modify it in product table too I think
i got the following error The key “(id)=(17)” already exists
Thank you
4
Answers
It’s a bit of a hack but the trick I’ve used is to update twice. e.g.
Another alternative is to remove the constraint and then add it back again but that’s even uglier.
Whatever the approach doing it in a single transaction is probably a good idea.
The attribute
id
must be primary key, thus the error. Also, One Must Not fiddle with the Primary Key Values because if they are used inFK_Constraints
or as Foreign Keys, such manipulation of Primary Key value can be disastrous.Notwithstanding, you one can achieve what you are trying using something known as
Common Table Expression
. You may look at followingsql
The last one is maybe good, but
like that:
Updating tables that reference this ID can be handled automatically if you set up the foreign key columns with an
on update cascade
clause: demoTo get rid of the
id
collision error, you can use an ordered batch update:You got the error because your primary key constraint is by default
not deferrable
, so the uniqueness of the id is checked row-by-row during theupdate
operation. Trying to update the first row withid=15
it already seesid=16
is occupied by the next row. If you force it to process things in reverse, each row first makes room for the next one to take over itsid
.It’s also possible to make your primary key constraint
deferrable
which makes PostgreSQL check for constraint violations at the end of transaction instead. Problem is, a column with a deferrable unique constraint cannot be used for foreign keys: demo2.@Frank Heikens raised a good point. You’re putting
id
column on double duty: one of uniquely identifying rows, another of defining order of some sort. By dispatching these functions to different columns you wouldn’t have to cascade identity changes all over the place whenever you just want to change order: demoYou can reorder things all you want an all previous foreign key associations remain untouched.