Прежде всего: утверждение о том, что пункты WITH
«хранят данные в памяти, пока сеанс жив», равно false . Конструкция WITH cursor_var AS (SELECT ...) LOOP
- это просто цикл курсора - такой же, как у цикла OPEN..FETCH..CLOSE
, который у вас есть. Тем не менее: WITH
циклы курсора могут понравиться, но кэширование магических данных не входит в их число.
Во-вторых: если вы что-то не указали, то в этом случае нет необходимости в PL / SQL. Строковая обработка курсора, как у вас, будет намного медленнее, чем один оператор SQL. (Ваш случай еще хуже, потому что вы делаете 5 скалярных подзапросов для каждого обновления).
Вот как вы можете достичь своей цели, используя одно выражение UPDATE
:
UPDATE rpt_list_cdo u
SET ( name_cdo, date_cdo, cod_cdo, log_cdo, data_cdo ) =
(
SELECT MAX(DECODE(sln.linkid,164,trim(sln.linkvalue),null)) name_cdo,
MAX(DECODE(sln.linkid,165,trim(sln.linkvalue),null)) date_cdo,
MAX(DECODE(sln.linkid,166,trim(sln.linkvalue),null)) cod_cdo,
MAX(DECODE(sln.linkid,167,trim(sln.linkvalue),null)) log_cdo,
MAX(DECODE(sln.linkid,168,trim(sln.linkvalue),null)) data_cdo
FROM sprlinks sln
WHERE sln.objectid = u.id
AND sln.linkid in (164,165,166,167,168))
WHERE 1=1
AND -- whatever other conditions you have in your act_rpt_list_cdo cursor
MERGE
также будет работать, но мне больше нравится UPDATE
в этом случае, потому что легче добавить любые другие условия, которые есть в вашем act_rpt_list_cdo
курсоре.