ORACLE数据库:如何修正测试环境在插入数据时,出现唯一性错误

--A
背景:撰写此文档,是为了处理这类错误,

--B
分析问题的产生原因:
1、 问题发生在客户使用Expdp/Impdp的方法,新建的数据库账号上。
2、 Expdp 时,先导出了序列对象,然后再导出使用这些序列的表。
3、 由于是在业务期间的操作,某些序列的信息被导出到DMP后,应用系统此时还在持续读取该序列值,作为对应表的主键值,插入到表中。之后,该表才被导出到DMP文件里。
4、 显然,此时表里的主键值,比保存在DMP文件里该序列的当前值,要大;故,当将此DMP文件的数据导入库后,使用序列的下一个值,将出现表的主键值重复的情况,就会报上述错误。
--C
显然,要消除此语句,只要让序列的输出值,大于表中主键字段的最大值即可。这一点实现起来并不难,关键是,如何确保表和序列的一一匹配?为此,需要设计表来保存两者的关系,如下结构:
create table t_bas_tabandseqs
(table_name varchar2(30) not null,
seq_name varchar2(30) not null,
column_name varchar2(30));
/
table_name :表名,必填项。
seq_name :该表主键对应的序列名,必填项。
column_name :表主键字段,辅助,主键只能一个字段。
alter table t_bas_tabandseqs add constraint pk_bas_tabandseqs primary key(table_name);
create unique index idx_ bas_tabandseqs on t_ bas_tabandseqs (seq_name);
--D 编写了个存储过程来修正序列的当前值,使得序列当前值大于表的主键最大值。
入参为:发生唯一性错误的索引;如上面的 PK_BD_SUPPLIER_L,
存储过程根据入参,找到所属的表,当此索引是由一个索引字段组成时,在辅助表:
t_bas_tabandseqs里搜索此表对应的序列,
然后对比表的主键最大值,及序列的下一个值,若序列值比主键最大值小,则更改序列步伐
属性(下个值跨过主键最大值),然后取序列的下一个值,此时,序列的当前值将大于主键最
大值,然后,再把序列的步伐改回1。
create or replace procedure p_bas_alterseqstartval(v_accid_idx in varchar2) as
v_maxval number;
v_nextval number;
v2_nextval number;
begin
for i in (select table_name, column_name, col_position from (select table_name, column_name, column_position col_position,
row_number() over(partition by table_name, index_name order by column_position desc) seq
from user_ind_columns where index_name=upper(v_accid_idx)) where seq=1 ) loop
if (i.col_position
ORACLE数据库:如何修正测试环境在插入数据时,出现唯一性错误
声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。



