我现在面临一个问题,在我们的旧数据库(postgres 9.4)的表里有一些重复的记录。我想确保不再产生重复的记录。
但我也想保留已经生成的重复行。因此,我不能在这些列(多列)上应用唯一约束。
我已经创建了一个触发器,它将检查行是否已经存在,并相应地引发异常。但是,当并发事务正在处理时,它也失败了。
例子:我创建了一个触发器,它可以检查行是否已经存在,并相应地引发异常。
TAB1
col1 | col2 | col3 |
------------------------------------
1 | A | B | --
2 | A | B | -- already present duplicates for column col2 and col3(allowed)
3 | C | D |
INSERT INTO TAB1 VALUES(4 , 'A' , 'B') ; -- This insert statement will not be allowed.
注意:我不能使用触发器。 我不能使用 冲突 由于数据库的旧版本。
大概,你不希望新的记录与历史记录重复。 如果是这样,你可以这样做,但需要修改表,并添加一个新的列。
alter table t add duplicate_seq int default 1;
然后更新这一列来识别现有的重复记录。
update t
set duplicate_seq = seqnum
from (select t.*, row_number() over (partition by col order by col) as seqnum
from t
) tt
where t.<primary key> = tt.<primary key>;
现在,创建一个唯一的索引或约束。
alter table t add constraint unq_t_col_seq on t(col, duplicate_seq);
当你插入行时, 不提供价值 duplicate_seq
. 默认为 1
. 这将与任何现有的值或最近输入的重复值发生冲突。 历史上的重复值将被允许。