简体   繁体   中英

Oracle merge sql no rows inserted

I'm using merge sql to find if the rows exist and then update or insert the data.

My problem is that if rows exist then update block works. But if not, there is no data inserted.

Is it because I use fixed data instead of datasource from q2?

Database version : oracle 9i

SQL:

merge into TBL_QTY q1
using (
select PROD_NO, PART_BATCH_NO, COND1_TYPE, BEG_DT, END_DT   
    from TBL_QTY
     WHERE PROD_NO = 'A111'
      AND PART_BATCH_NO = 'BAT0000171624'
      AND COND1_TYPE = '172'
      AND COND2_TYPE = 'XXX'
      AND COND3_TYPE =  'XXX'
      AND BEG_DT = '20201225'
      AND END_DT = '20201225' ) q2
      on 
(  q1.PROD_NO = q2.PROD_NO
  and q1.PART_BATCH_NO = q2.PART_BATCH_NO
  and q1.COND1_TYPE = q2.COND1_TYPE
  and q1.BEG_DT = q2.BEG_DT
  and q1.END_DT= q2.END_DT)
WHEN MATCHED THEN 
    update  SET q1.OBTAIN_QTY    = 15 ,     
            q1.SALE_QTY      = 15 
WHEN NOT MATCHED THEN
    INSERT (PROD_NO, PART_BATCH_NO, COND1_TYPE, BEG_DT
           ,END_DT , OBTAIN_QTY   , SALE_QTY           )
     VALUES('A111' ,'BAT0000171624'  ,'172','20201225'   
           ,'20201225', 17, 17)

The USING subquery selects values from the same table you want to insert into. This means it returns no rows when the values in your WHERE clause don't exist in that table.

Why doesn't that trigger the WHEN NOT MATCHED branch as you expect? Because you have an empty set : there is nothing for Oracle to match against, it's not even evaluated.

The way MERGE works is, we get a set of rows from the USING query and compare them with the contents of the target: the match is evaluated and the appropriate branch is triggered for each row in the USING set.

To make your code work you must have rows in the USING subsubquery. The normal way to do that is to select literals from DUAL. (Caution: the following code is free-styled and untested, so may contain syntax errors which are left as an exercise for the reader).

merge into TBL_QTY q1
using (
select 'A111' as prod_no
       ,'BAT0000171624' as part_batch_no
       ,'172' as cond1_type
       ,'20201225' as beg_dt  
      ,'20201225' as end_dt
      , 17 as obtain_qty
      , 17 as sale_qty ) q2
      on 
(  q1.PROD_NO = q2.PROD_NO
  and q1.PART_BATCH_NO = q2.PART_BATCH_NO
  and q1.COND1_TYPE = q2.COND1_TYPE
  and q1.BEG_DT = q2.BEG_DT
  and q1.END_DT= q2.END_DT)
WHEN MATCHED THEN 
   update  SET q1.OBTAIN_QTY    = 15     
               ,q1.SALE_QTY      = 15 
WHEN NOT MATCHED THEN
   INSERT (PROD_NO, PART_BATCH_NO, COND1_TYPE, BEG_DT
           ,END_DT , OBTAIN_QTY   , SALE_QTY           )
   VALUES (q2.PROD_NO, q2.PART_BATCH_NO, q2.COND1_TYPE, q2.BEG_DT
           ,q2.END_DT , q2.OBTAIN_QTY   , q2.SALE_QTY           )

If you need to do this for multiple rows, you can use UNION ALL to weld together selects on DUAL in the USING subquery.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM