PL/SQL循环复制关联表数据报错:唯一约束冲突求助
PL/SQL数据复制逻辑问题修复
问题根源
- 游标过滤范围错误:原游标
e仅按banka = p_banka_iz过滤,会取出该银行下所有tab_ol_mv_skupina_setup记录,导致每条新插入的tab_ol_mv_setup记录都重复复制全部skupina数据,触发唯一约束冲突。 - 未获取新生成的关联ID:原代码中使用的
w_info_vrstice_setup.id是源记录的旧ID,而非插入tab_ol_mv_setup后生成的新ID(若ID为序列/自增生成),导致关联关系错误。
修复后的代码
DECLARE w_info_vrstice_sif_setup tab_ol_mv_sif_setup%rowtype; w_info_vrstice_setup tab_ol_mv_setup%rowtype; w_info_vrstice_skupina_setup tab_ol_mv_skupina_setup%rowtype; w_new_setup_id tab_ol_mv_setup.id%TYPE; -- 存储新插入的setup记录ID -- 游标:获取源银行的sif_setup记录 CURSOR c IS SELECT a.* FROM tab_ol_mv_sif_setup a WHERE a.banka = p_banka_iz; -- 游标:获取源银行的setup记录 CURSOR d IS SELECT b.* FROM tab_ol_mv_setup b WHERE b.banka = p_banka_iz; -- 带参数游标:仅获取指定原始setup ID对应的skupina记录 CURSOR e(p_original_setup_id tab_ol_mv_setup.id%TYPE) IS SELECT k.* FROM tab_ol_mv_skupina_setup k WHERE k.banka = p_banka_iz AND k.id_mv = p_original_setup_id; -- 关联原始setup的ID,缩小查询范围 BEGIN -- 第一步:复制tab_ol_mv_sif_setup FOR i IN c LOOP w_info_vrstice_sif_setup := i; w_info_vrstice_sif_setup.tvoril := NULL; w_info_vrstice_sif_setup.tvoril_datum := NULL; w_info_vrstice_sif_setup.id_prijave := NULL; w_info_vrstice_sif_setup.banka := p_banka_v; INSERT INTO tab_ol_mv_sif_setup VALUES w_info_vrstice_sif_setup; END LOOP; -- 第二步:复制tab_ol_mv_setup,并关联复制对应skupina数据 FOR j IN d LOOP w_info_vrstice_setup := j; w_info_vrstice_setup.tvoril := NULL; w_info_vrstice_setup.tvoril_datum := NULL; w_info_vrstice_setup.id_prijave := NULL; w_info_vrstice_setup.banka := p_banka_v; -- 插入新setup记录并获取生成的新ID INSERT INTO tab_ol_mv_setup VALUES w_info_vrstice_setup RETURNING id INTO w_new_setup_id; -- 关键:获取新生成的关联ID -- 第三步:复制当前setup对应的skupina记录 FOR l IN e(j.id) LOOP -- 传入原始setup的ID,仅处理对应关联数据 w_info_vrstice_skupina_setup := l; w_info_vrstice_skupina_setup.id_mv := w_new_setup_id; -- 使用新生成的setup ID w_info_vrstice_skupina_setup.tvoril := NULL; w_info_vrstice_skupina_setup.tvoril_datum := NULL; w_info_vrstice_skupina_setup.id_prijave := NULL; w_info_vrstice_skupina_setup.banka := p_banka_v; INSERT INTO tab_ol_mv_skupina_setup VALUES w_info_vrstice_skupina_setup; END LOOP; END LOOP; END; /
关键修复说明
- 带参数游标:通过传入原始
tab_ol_mv_setup的ID,确保只复制当前记录对应的关联数据,避免批量重复插入。 - RETURNING INTO:获取新插入的
tab_ol_mv_setup记录ID,保证关联的skupina数据使用正确的新ID。 - 缩小数据范围:第三步仅处理当前setup记录对应的skupina数据,彻底避免重复操作导致的唯一约束冲突。
内容的提问来源于stack exchange,提问作者Videk
相关产品推荐
相关产品推荐

