Вы используете CURSOR
и циклы без причины, когда все ваши обновления могут быть преобразованы в обновление и оператор MERGE
.
Ниже приведен оператор обновления для случая C1%rowcount=1
,который не нужно было помещать в цикл даже раньше.
UPDATE mmdeal0_nwap
SET wap1 = p_wap
WHERE dealno = p_dealno
AND dealdt = p_fdt
AND securitycd = p_securitycd
AND securitytype = p_securitytype
AND selforconstituent = p_selforconstituent;
Второе обновление преобразовано в MERGE
MERGE INTO mmdeal0_nwap t USING (
SELECT i.*,
( ( nvl(i.pc_wap1,0) * nvl(i.pc_stk,0) ) + ( nvl(v_pofv,0) * nvl(i.prc,0) ) ) - ( nvl(v_sofv
,0) * nvl(i.pc_wap1,0) ) / i.ownst AS new_wp --your calculation for the value of WP to be updated
FROM (
SELECT d.securitycd scd,
d.dealno dno,
s.ownstk ownst,
LAG(s.ownstk) OVER(
ORDER BY d.dealdt
) pc_stk,
d.dealtype dtype,
d.securitytype stype,
d.selforconstituent sforco,
d.dealdt ddate,
d.price prc,
d.facevalue fv,
LAG(d.facevalue) OVER(
ORDER BY d.dealdt
) pc_fv,
d.wap1 wp,
LAG(d.wap1) OVER(
ORDER BY d.dealdt
) pc_wap1,
CASE
WHEN d.dealtype = 'PO' THEN d.facevalue
END
AS v_pofv,
CASE
WHEN d.dealtype = 'SO' THEN d.facevalue -- IF conditions converted to CASE
END
AS v_sofv
FROM mmdeal0_nwap d
INNER JOIN mmstock1 s ON d.securitycd = s.securitycd
WHERE d.dealdt >= p_fdt AND d.dealno = p_dealno AND d.facevalue > 0 AND d.dealtype IN (
'PO',
'SO'
) AND d.selforconstituent = 'S' AND d.securitytype = 'DGS'
) i
WHERE i.ownst > 0 --outer IF condition
)
ON (
t.dealno = s.dno AND t.dealdt = s.ddate AND t.securitycd = s.scd AND t.securitytype = s.stype AND
t.selforconstituent = s.sforco
) --where clause from your update
WHEN MATCHED THEN UPDATE SET t.wap1 = s.new_wp;
Обратите внимание, что код не проверен , поэтому вам, возможно, придется исправить некоторые синтаксические ошибки / ошибки редактирования, которые я, возможно, допустил.Но я думаю, что дал вам достаточно справедливое представление о том, как действовать.