【发布时间】:2015-09-06 15:29:40
【问题描述】:
我确定这很常见,但 Google 没有提供帮助。我正在尝试在 PostgreSQL 9.1 中编写一个简单的存储过程,它将从父 cpt 表中删除重复的条目。父表cpt被子表lab引用定义为:
CREATE TABLE lab (
recid serial NOT NULL,
cpt_recid integer,
........
CONSTRAINT cs_cpt FOREIGN KEY (cpt_recid)
REFERENCES cpt (recid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE RESTRICT,
...
);
我遇到的最大问题是如何获取失败的记录,以便我可以在EXCEPTION 子句中使用它来将子行从lab 移动到一个可接受的键,然后循环返回并删除cpt 表中不必要的记录。
这是(非常错误的)代码:
CREATE OR REPLACE FUNCTION h_RemoveDuplicateCPT()
RETURNS void AS
$BODY$
BEGIN
LOOP
BEGIN
DELETE FROM cpt
WHERE recid IN (
SELECT recid
FROM (
SELECT recid,
row_number() over (partition BY cdesc ORDER BY recid) AS rnum
FROM cpt) t
WHERE t.rnum > 1)
RETURNING recid;
IF count = 0 THEN
RETURN;
END IF;
EXCEPTION WHEN foreign_key_violation THEN
RAISE NOTICE 'fixing unique_violation';
RAISE NOTICE 'recid is %' , recid;
END;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
【问题讨论】:
-
你试过隐藏列 ctid 吗?即使所有可见列都相同,它也有助于删除重复项。
标签: database postgresql exception-handling foreign-keys plpgsql