我有两个字段的唯一索引表,lane_id和position。
现在,我想使用此查询更新行:
UPDATE "teams_ticket" SET "position" = ("teams_ticket"."position" + 1) WHERE ("teams_ticket"."lane_id" = 1 AND "teams_ticket"."position" >= 0)
最终:
duplicate key value violates unique constraint "teams_ticket_position_bfcce9fa_uniq"
如果我有一张以上的票。
我该如何解决这个问题?
答案 0 :(得分:0)
您可以使用游标逐个更新它们。
DO $$
DECLARE r record;
BEGIN
FOR r IN SELECT lane_id, position FROM teams_ticket WHERE lane_id=1 AND position >= 0 ORDER BY position DESC
LOOP
UPDATE teams_ticket SET position=position+1 WHERE position=r.position AND lane_id=r.lane_id;
END LOOP;
END$$;
答案 1 :(得分:0)
您需要deferrable
个约束(实际上是暂时推迟)。 Deferrable意味着不会立即检查约束(例如:在重写索引元组时),但在事务(或语句)结束时,所有行都已更新:
- \ t tmp.sql
CREATE TABLE positions
( seq SERIAL PRIMARY KEY
, position INTEGER NOT NULL UNIQUE DEFERRABLE
);
INSERT INTO positions(position)
SELECT generate_series(1,10) gs;
BEGIN;
SET CONSTRAINTS ALL DEFERRED;
update positions
SET position= position +1
WHERE seq <= 6 ;
SELECT * FROM positions ;
UPDATE positions SET position= position +1
WHERE seq > 6
;
SELECT * FROM positions ;
UPDATE positions SET position= position +1
;
SELECT * FROM positions ;
COMMIT;
答案 2 :(得分:-1)
你可以尝试
UPDATE teams_ticket t
SET position = q.position + 1
FROM (
SELECT lane_id, position
FROM teams_ticket
WHERE lane_id = 1
AND position >= 0
ORDER BY lane_id, position DESC
) q
WHERE t.lane_id = q.lane_id
AND t.position = q.position