Oracle:Merge Into 实例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle:Merge Into 实例相关的知识,希望对你有一定的参考价值。

基础语法:
MERGE INTO [your table-name] [rename your table here] 
USING ( [write your query here] )[rename your query-sql and using just like a table] 
ON ([conditional expression here] AND [...]...) 
WHEN MATHED THEN [here you can execute some update sql or something else ] 
WHEN NOT MATHED THEN [execute something else here ! ] 
实例:
insert into TPT_PC_PRICE(tpt_nbr,tpt_user,tpt_vend,tpt_sort,tpt_part,tpt_desc1,tpt_price_old,tpt_price,tpt_curr, tpt_start,tpt_ct_desc,tpt_vat,tpt_um,tpt_um_rate,tpt_char1,
    tpt_char2 ,tpt_char3,tpt_char4,tpt_char5,tpt_char6,tpt_qty1,tpt_qty2,tpt_pst,tpt_rmks,tpt_w_price,TPT_TYPE,Tpt_Rate)
    select pc_nbr, var_usr_user,pc_vend, vd_sort, pc_part, pt_desc1, 0.00 as price_old,pc_price,pc_curr, pc_start, ct_desc, pc_vat, pc_um,PC_UM_RATE_M e,pc_char1,
          pc_char2, pc_char3, pc_char4,pc_char5,pc_char6,pc_w_price, pc_qty2,pc_pst,pc_rmks,pc_w_price,pc_type,PC_CUSTOM_VAT
    from pc_mstr join vd_mstr on pc_vend = vd_addr
                 join pt_mstr on pc_part = pt_part
                 join ct_mstr on vd_cr_terms = ct_code
    where -- (((pc_vend >=  var_vend_fr) or (var_vend_fr is null))  and ((pc_vend <=var_vend_to) OR (var_vend_to is null)))  and
          --(((pc_part >=  var_part_fr) or (var_part_fr is null))  and ((pc_part <=var_part_to) OR (var_part_to is null)))
         func_vd_perm(vd_exploiter, var_usr_user) = 1
        and between2(vd_exploiter, var_dev1, var_dev2)=1
        and between2(pc_vend, var_vend_fr, var_vend_to) =1
       and between2(pc_part, var_part_fr ,var_part_to) = 1
       and pc_start>= var_data1 and pc_start <= var_data2
        --  AND trunc(sysdate, ‘DD‘) between pc_start and pc_expire 
   and pc_pst = 0;

    MERGE INTO TPT_PC_PRICE A
            USING (select B.pc_vend,B.pc_part,B.pc_price,B.pc_type 
                   from  pc_mstr B join 
                      (select pc_vend,pc_part,max(pc_expire) as pc_expire_old,pc_type
                          from pc_mstr join TPT_PC_PRICE on  tpt_vend =pc_vend and tpt_part = pc_part
                                       where pc_pst = 1
                                       group by pc_vend, pc_part,pc_type
                       )H on B.pc_vend = H.pc_vend and B.pc_part = H.pc_part and H.pc_expire_old =B.pc_expire and H.pc_type=B.pc_type 
                                       
         ) T  on (pc_vend = tpt_vend and pc_part = tpt_part and pc_type=tpt_type)
            WHEN MATCHED THEN
                UPDATE SET tpt_price_old = T.pc_price
                where tpt_user = var_usr_user and  
                     --(((tpt_vend >=  var_vend_fr) or (var_vend_fr is null))  and ((tpt_vend <=var_vend_to) OR (var_vend_to is null)))  and
                      -- (((tpt_part >=  var_part_fr) or (var_part_fr is null))  and ((tpt_part <=var_part_to) OR (var_part_to is null)));
                     between2(tpt_vend, var_vend_fr, var_vend_to) = 1  and 
                     between2(tpt_part, var_part_fr ,var_part_to) = 1 ;
异常处理:

跟踪结果:

技术分享

原因分析:(注:版本:Oracle 9i)

根据异常描述可以判断是数据匹配上的问题,且问题大致是数据出现一对多的关系,导致异常。

现附上异常数据寻找思路:

技术分享
SELECT pc_vend,pc_part,pc_type FROM (
-------------------------------------主表数据------------------------------------------------------------
select pc_vend,pc_part,pc_type from (
select pc_nbr, KXX003,pc_vend, vd_sort, pc_part, pt_desc1, 0.00 as price_old,pc_price,pc_curr, pc_start, ct_desc, pc_vat, pc_um,PC_UM_RATE_M e,pc_char1,
          pc_char2, pc_char3, pc_char4,pc_char5,pc_char6,pc_w_price, pc_qty2,pc_pst,pc_rmks,pc_w_price,pc_type,PC_CUSTOM_VAT
    from pc_mstr join vd_mstr on pc_vend = vd_addr
                 join pt_mstr on pc_part = pt_part
                 join ct_mstr on vd_cr_terms = ct_code
    where 
         func_vd_perm(vd_exploiter, KXX003) = 1
        and between2(vd_exploiter, PQ002, PQ002)=1
        and between2(pc_vend, 7B11R1001, 7B11R1001) =1
       and between2(pc_part, ‘‘ ,ZZZZZZZZZZZZ) = 1
       and pc_start>= to_date(2017-09-01,yyyy-mm-dd) and pc_start <= to_date(2017-09-06,yyyy-mm-dd)
        --  AND trunc(sysdate, ‘DD‘) between pc_start and pc_expire 
   and pc_pst = 0
   )
-------------------------------------主表数据 end------------------------------------------------------------
UNION ALL 
-----------------------------------匹配表数据--------------------------------------------------------------------
   select B.pc_vend,B.pc_part,B.pc_type 
                   from  pc_mstr B join 
                      (select C.pc_vend,C.pc_part,max(C.pc_expire) as pc_expire_old,C.pc_type
                          from pc_mstr C join 
                          (select pc_vend tpt_vend,pc_part tpt_part,pc_type tpt_type from (
select pc_nbr, KXX003,pc_vend, vd_sort, pc_part, pt_desc1, 0.00 as price_old,pc_price,pc_curr, pc_start, ct_desc, pc_vat, pc_um,PC_UM_RATE_M e,pc_char1,
          pc_char2, pc_char3, pc_char4,pc_char5,pc_char6,pc_w_price, pc_qty2,pc_pst,pc_rmks,pc_w_price,pc_type,PC_CUSTOM_VAT
    from pc_mstr join vd_mstr on pc_vend = vd_addr
                 join pt_mstr on pc_part = pt_part
                 join ct_mstr on vd_cr_terms = ct_code
    where 
         func_vd_perm(vd_exploiter, KXX003) = 1
        and between2(vd_exploiter, PQ002, PQ002)=1
        and between2(pc_vend, 7B11R1001, 7B11R1001) =1
       and between2(pc_part, ‘‘ ,ZZZZZZZZZZZZ) = 1
       and pc_start>= to_date(2017-09-01,yyyy-mm-dd) and pc_start <= to_date(2017-09-06,yyyy-mm-dd)
        --  AND trunc(sysdate, ‘DD‘) between pc_start and pc_expire 
   and pc_pst = 0
   ))
                          
                          on  tpt_vend =pc_vend and tpt_part = pc_part
                                       where pc_pst = 1
                                       group by C.pc_vend, C.pc_part,C.pc_type
                       )H on B.pc_vend = H.pc_vend and B.pc_part = H.pc_part and H.pc_expire_old =B.pc_expire and H.pc_type=B.pc_type
-----------------------------------匹配表数据 end--------------------------------------------------------------------
)
GROUP BY pc_vend,pc_part,pc_type
HAVING COUNT(1) > 2
View Code

 

以上是关于Oracle:Merge Into 实例的主要内容,如果未能解决你的问题,请参考以下文章

oracle merge into 表里面的一部分数据怎样做?

ORACLE关于merge into用法!

Oracle merge into 的效率问题

oracle merge into 的这个该怎么用

mybatis 使用oracle merge into 语句踩坑实录

Oracle 使用MERGE INTO 语句更新数据