На вашем месте я бы хотел превратить это в одно выражение MERGE
, что-то вроде:
MERGE INTO phone tgt
USING (SELECT t1.key_colval,
t2.user_id,
CASE WHEN t2.user_id IS NULL THEN 'N' ELSE 'Y' END INDICATOR
CASE WHEN row_number() OVER (PARTITION BY t1.colval ORDER BY t1.colval) = 1 THEN 'PRI'
ELSE 'SCD'
END phone_number_type,
SUBSTR(tuv.MOBILE,1,3) PHONE_AREA_CODE,
SUBSTR(tuv.MOBILE,5,3)||SUBSTR(tuv.MOBILE,9) PHONE_NUMBER,
NULL PHONE_EXTENSION
FROM Table1 t1
LEFT OUTER JOIN (SELECT key_colval,
user_id
FROM (SELECT user_id,
key_colval,
row_number() OVER (PARTITION BY key_colval ORDER BY hire_date DESC) rn
FROM table2
WHERE job_title = 'Sales Rep'
AND status = 'Active') t
WHERE rn = 1) t2 ON t1.key_colval = t2.key_colval
INNER JOIN tmp_user_view tuv ON tuv.key_colval = t1.key_colval AND ((t2.user_id IS NOT NULL AND tuv.user_id = t2.user_id) OR t2.user_id IS NULL)
WHERE t1.CATEGORY = 'T'
AND ROWNUM <= 2 -- there's no ordering mentioned in your calling_PHONE_upd cursors, so if there should be, you'd need another method of working out the correct 2 rows to return and in which order
) src
ON (tgt.key_colval = src.key_colval -- plus additional columns that make the join between the tgt table and src subquery produce a 1-2-1 mapping
)
WHEN MATCHED THEN
UPDATE SET tgt.phone_number_type = src.phone_number_type -- add in the other columns (not the ones in the ON clause above!)
WHEN NOT MATCHED THEN
INSERT (tgt.key_colval, ...) -- list the other columns being inserted into
VALUES (src.key_colval, ...); -- list the other source columns being inserted
Я пришел к этому утверждению после прохождения вашей логики и преобразования ручных объединенных вложенных циклов (циклов курсора в циклах курсора) в один оператор выбора, а затем с помощью этого слияния вместо вставки или обновления заявления.
Это должно значительно улучшить ситуацию, поскольку теперь вы можете позволить оптимизатору определить наилучший способ объединения таблиц и исключить все переключения контекста между SQL и PL / SQL.
Я бы тоже не стал заниматься столами для постановки; просто используйте запрос, который заполнил промежуточные таблицы непосредственно в исходном подзапросе оператора Merge. Это экономит ваше время на усечение и вставку данных.
N.B. Мое утверждение явно не проверено, поскольку вы не предоставили полный тестовый пример с образцами данных и ожидаемым результатом. Если это не сработает так, как вы ожидаете, я бы порекомендовал вам исправить это для вашего случая, вместо того чтобы переходить к высокопроцедурному коду, который у вас есть в настоящее время.