1) Вы заменяете значимую ошибку бессмысленной. Кроме того, если у вас нет set output on
, ошибка будет полностью пропущена. Лучше всего просто удалить блок исключения. Если вы не можете этого сделать, вы должны сбросить как минимум SQLERRM
и, вероятно, DBMS_UTILITY.FORMAT_ERROR_BACKTRACE
до DBMS_OUTPUT
. Чтобы правильно отлавливать и записывать ошибки, вам необходимо передать подробности исключения в отдельную процедуру, которая будет использовать автономную транзакцию для записи этих сведений в таблицу. Тем не менее, даже в этом случае лучше повторно вызвать ошибку после ее записи.
2) В большинстве случаев фиксация каждой X-записи является плохой практикой. Если все эти записи обновляются вместе, то они должны быть частью одной транзакции.
3) Вы можете сделать это в одном выражении, используя UPDATE
или MERGE
. Обычно это предпочтительнее, так как избегает дополнительных переключений контекста. Лично мне нравится MERGE
в этом сценарии:
MERGE INTO item_loc il
USING (SELECT item,
loc,
loc_type,
source_method,
primary_supp,
source_wh
FROM (SELECT dc_vert.item,
dc_vert.loc,
dc_vert.loc_type,
dc_vert.source_method,
dc_vert.primary_supp,
w.primary_vwh source_wh,
dc_vert.actie,
MAX(dc_vert.actie) OVER (PARTITION BY dc_vert.item, dc_vert.loc) actie_max,
COUNT(dc_vert.primary_supp) OVER (PARTITION BY dc_vert.item, dc_vert.loc) primary_count
FROM dc_item_loc_pim_lms dc_vert,
item_supplier isu,
store sto,
wh w
WHERE dc_vert.primary_supp IS NOT NULL
AND isu.item = dc_vert.item
AND dc_vert.primary_supp = isu.supplier
AND w.wh = dc_vert.source_wh
AND sto.store = dc_vert.loc
AND isu.supp_discontinue_date >= SYSDATE)
WHERE actie = actie_max AND primary_count = 1) itemloc
ON (il.item = itemloc.item AND il.loc = itemloc.loc)
WHEN MATCHED THEN
UPDATE SET
il.source_method = itemloc.source_method,
il.loc_type = itemloc.loc_type,
il.primary_supp = itemloc.primary_supp,
il.source_wh = itemloc.source_wh,
il.last_update_datetime = SYSDATE;