在现有的应用程序中,我有一个没有主键的表,其中(很少)有重复的行。为了与另一个系统集成,我需要在表中添加一列,使这些重复行唯一。该表基本上是:
+------+---------+--------+ | txn# | detail# | amount | +------+---------+--------+
我可以为每个现有行使用递增的seq#,但是,应用程序更改将采用现有的“几乎键”(基本上是事务#etail#),并递增此组合的序列号(因此,例如,我将有两行用于txn#1,细节#1,并且seq#1用于第一个,seq#2用于第二个,如果txn#513,细节#44有3个重复行,这些将具有seq#1,2,3恰当。这是理想的(从支持的角度来看),如果应用程序前后的数据更改同样如此。是否有一些简单的方法来创建此列,或者我是否需要手动循环行,每次txn#或detail#更改时重置使用的序列?
编辑添加:该应用程序部署在Postgresql 7.4& 8.1,解决方案需要适用于这两个版本。
答案 0 :(得分:1)
如果你的专栏“几乎是独一无二的”,我即每个值没有多少重复,您可以使用以下语法:
ALTER TABLE mytable ADD seq INT;
UPDATE mytable mo
SET seq =
(
SELECT COUNT(*)
FROM mytable mi
WHERE mi.txn = mo.txn
AND mi.detail = mo.detail
AND mi.ctid <= mo.ctid
)
ALTER TABLE mytable ALTER COLUMN seq SET NOT NULL;
ALTER TABLE mytable DROP CONSTRAINT t_mytable_pkey; -- the name of your current primary key
ALTER TABLE mytable ADD CONSTRAINT t_mytable_pkey PRIMARY KEY (txn, detail, seq);
如果没有太多重复,这将很快完成。
答案 1 :(得分:0)
您可以更改表格以创建新的主键列。然后,您可以在该表上创建一个插入和更新触发器,它将两个列组合在一起并将它们插入到右侧。