Обработка MERGE с дубликатами - PullRequest
1 голос
/ 01 апреля 2019

У меня есть порядок таблиц и намерения

oano  code  slno  
0001  swg1   1
0001  swg2   2
0001  swg1   3
0001  swg4   4
0001  swg1   5

намеревается

intend   oano  code  slno
i/1      0001   swg1  1
i/1      0001   swg1  3
i/1      0001   swg2  2  
i/3      0001   swg4  4
i/3      0001   swg1  5

Я хочу обновить серийный номер в таблице намерений на основе таблицы OA, как указано выше. Статус слияния, который я использовал:

MERGE INTO ITBG_Intend_ITEMS target
USING (select oano, pcode, slno
           from itbg_order_items
           group by oano, pcode,SLNO
      ) source
ON
(target.icode = source.pcode and target.Oano = source.Oano )
WHEN MATCHED THEN UPDATE
    SET target.slno= source.slno

;

с ошибкой: ORA-30926: невозможно получить стабильный набор строк в исходных таблицах

Пожалуйста, помогите

Ответы [ 2 ]

0 голосов
/ 04 апреля 2019

Проблема в том, что для oano = 0001 и code = swg1 у вас есть три значения slno: 1, 3, 5. Таким образом, Oracle не знает, какое из них использовать. Если вы хотите минимальное или максимальное значение, используйте min() или max() в исходной части и удалите slno из group by предложения:

  merge into itbg_intend_items tgt
  using (select oano, pcode, min(slno) slno
           from itbg_order_items
           group by oano, pcode) src
  on (tgt.icode = src.pcode and tgt.oano = src.oano)
  when matched then update set tgt.slno= src.slno

Но если вы хотите назначить все значения, которые появляются в исходной таблице, вы должны соотнести строки как-то . Это «как-то» можно сделать, например, назначив номера строкам и присоединив таблицы таким образом. Такие подготовленные данные могут быть использованы в качестве источника в вашем merge утверждении:

merge into itbg_intend_items tgt
using (
  select rwd, oano, pcode, slno
    from (select oano, pcode, slno, 
                 row_number() over (partition by oano, pcode order by null) rn 
           from itbg_order_items)
    join (select rowid rwd, oano, icode pcode, 
                 row_number() over (partition by oano, icode order by null) rn 
           from itbg_intend_items)
    using (oano, pcode, rn)) src
on (tgt.icode = src.pcode and tgt.oano = src.oano and tgt.rowid = src.rwd)
when matched then update set tgt.slno= src.slno

Демоверсия dbfiddle

Конечно, могут быть некоторые проблемы, например, недостаточно значений в источнике для заполнения цели. Или вам может потребоваться конкретный заказ (в этом случае измените порядок на row_number() с). Все это можно сделать, но вы должны сказать нам, что вы хотите в таких ситуациях.

0 голосов
/ 01 апреля 2019

Merge не будет работать, если в исходной таблице есть несколько совпадений для записи в целевой таблице.Вместо этого вы можете использовать update + join:

UPDATE 
(
SELECT ITBG_Intend_ITEMS.slno as target_slno, itbg_order_items.slno as source_slno
 FROM ITBG_Intend_ITEMS
 INNER JOIN itbg_order_items
 ON ITBG_Intend_ITEMS.icode = itbg_order_items.pcode and ITBG_Intend_ITEMS.Oano = itbg_order_items.Oano
) joined
SET joined.target_slno = joined.source_slno
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...