Merge 主键冲突问题

<pre name="code" class="sql">merge into t47_id_deposit tid
  using t47_id_deposit_tmp tit
  on (tid.Acct_num = tit.Acct_num and tid.Party_id = tit.Party_id)
 
  when not matched then
    insert
      (tid.Acct_num, --  账号
       tid.Acct_modifier_num, --账号修饰符
       tid.Party_id, --  客户号
       tid.Host_cust_id, --  原客户号
       tid.Party_chn_name, --当事人中文名称
       tid.Acct_type_cd, --原账户类型
       tid.Aml_Acct_type_cd, --AML账户类型
       tid.Acct_category_cd, --账户类别
       tid.IB_property_cd, --外汇账户性质代码
       tid.IB_type_cd, --外汇账户种类
       tid.Organkey, --机构
       tid.Currency_cd, --  币种
       tid.Subjectno, --  科目号
       tid.Open_dt, --开户时间
       tid.Acct_Processing_Dt, --  起息日期
       tid.Mature_dt, --  到期日期
       tid.Last_occur_dt, --  上笔发生日期
       tid.Close_dt, --销户时间
       tid.Open_amt, --开户金额
       tid.Last_amt_val, --昨日余额
       tid.Amt_val, --余额
       tid.Token_id, --凭证号
       tid.Card_no, --卡号
       tid.Cash_transfer_cd, --钞汇标志
       tid.Acct_status_cd, --账户状态
       tid.Int_cal_method_cd, --计息标志
       tid.Cust_manager, --揽存人
       tid.Last_upd_dt, --上次更新时间
       tid.ACCT_ORG_NUM, --帐务机构号
       tid.BIZ_TYPE_CD, --业务代号代码
       tid.PERD_CD)
    values
      (tit.Acct_num, --  账号
       tit.Acct_modifier_num, --账号修饰符
       tit.Party_id, --  客户号
       tit.Host_cust_id, --  原客户号
       tit.Party_chn_name, --当事人中文名称
       tit.Acct_type_cd, --原账户类型
       tit.Aml_Acct_type_cd, --AML账户类型
       tit.Acct_category_cd, --账户类别
       tit.IB_property_cd, --外汇账户性质代码
       tit.IB_type_cd, --外汇账户种类
       tit.Organkey, --机构
       tit.Currency_cd, --  币种
       tit.Subjectno, --  科目号
       tit.Open_dt, --开户时间
       tit.Acct_Processing_Dt, --  起息日期
       tit.Mature_dt, --  到期日期
       tit.Last_occur_dt, --  上笔发生日期
       tit.Close_dt, --销户时间
       tit.Open_amt, --开户金额
       tit.Last_amt_val, --昨日余额
       tit.Amt_val, --余额
       tit.Token_id, --凭证号
       tit.Card_no, --卡号
       tit.Cash_transfer_cd, --钞汇标志
       tit.Acct_status_cd, --账户状态
       tit.Int_cal_method_cd, --计息标志
       tit.Cust_manager, --揽存人
       tit.Last_upd_dt, --上次更新时间
       tit.ACCT_ORG_NUM, --帐务机构号
       tit.BIZ_TYPE_CD, --业务代号代码
       tit.PERD_CD);
       
       select * from table(dbms_xplan.display());
       Plan hash value: 778631474
 
-----------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name               | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------------------
|   0 | MERGE STATEMENT                |                    |  2701 |  1519K|  5430   (1)| 00:01:06 |
|   1 |  MERGE                         | T47_ID_DEPOSIT     |       |       |            |          |
|   2 |   VIEW                         |                    |       |       |            |          |
|   3 |    NESTED LOOPS OUTER          |                    |  2701 |   957K|  5430   (1)| 00:01:06 |
|   4 |     TABLE ACCESS FULL          | T47_ID_DEPOSIT_TMP |  2701 |   474K|    22   (0)| 00:00:01 |
|*  5 |     TABLE ACCESS BY INDEX ROWID| T47_ID_DEPOSIT     |     1 |   183 |     2   (0)| 00:00:01 |
|*  6 |      INDEX UNIQUE SCAN         | PK_T47_ID_DEPOSIT  |     1 |       |     1   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   5 - filter("TID"."PARTY_ID"(+)="TIT"."PARTY_ID")
   6 - access("TID"."ACCT_NUM"(+)="TIT"."ACCT_NUM")
   '
   
   select count(*),Acct_num from (
   select  tit.Acct_num from t47_id_deposit_tmp tit
   minus
   select tit.Acct_num from t47_id_deposit tid ,t47_id_deposit_tmp tit
   where "TID"."PARTY_ID"(+)="TIT"."PARTY_ID"
   and "TID"."ACCT_NUM"(+)="TIT"."ACCT_NUM") group by Acct_num
   having count(*) >1
   
   select tid.Acct_num from  t47_id_deposit tid where  tid.Acct_num in (
   select a1 from (select tit.Acct_num a1 ,tid.Acct_num  a2 from t47_id_deposit tid ,t47_id_deposit_tmp tit
   where "TID"."PARTY_ID"(+)="TIT"."PARTY_ID"
   and "TID"."ACCT_NUM"(+)="TIT"."ACCT_NUM"
   and tid.Acct_num is null))

   
156040121501000243230
2570101211030003597610
1560401211030010197410

select * from t47_id_deposit_tmp a where a.acct_num='156040121501000243230'
select * from t47_id_deposit a where a.acct_num ='156040121501000243230'

156040121501000243230	15601233078220040922003X
156040121501000243230	15601133078220040922003X


表t47_id_deposit tid上有主键,主键字段为acct_num,此时执行merge语句报主键错误。

(tid.Acct_num = tit.Acct_num )改成这2个关联后就能插入,原因为
156040121501000243230	15601233078220040922003X
156040121501000243230	15601133078220040922003X

通过156040121501000243230账号能关联上,但是两个条件结合后就无法关联。
改为只通过
tid.Acct_num = tit.Acct_num
关联

导致选择了插入,而原表中已经存在此数据,本应该修改,选择插入就报错了。






                                    
原文地址:https://www.cnblogs.com/hzcya1995/p/13351948.html