我有以下plsql语句:
DECLARE
VPERIODID VARCHAR2 (10);
vPROCSESSID NUMBER;
VAUDITORID NUMBER;
CURSOR c
IS
SELECT *
FROM view_cost_noabc
WHERE OAUDITORID = 477 AND FL <> 'Ο' AND yearid < 2015
ORDER BY ID;
TYPE nt_type IS TABLE OF c%ROWTYPE;
l_arr nt_type;
TYPE vPREVPERIODVALUE IS TABLE OF NUMBER;
vprev vPREVPERIODVALUE;
dml_errors EXCEPTION;
BEGIN
SELECT fn_periodcurrent INTO vPERIODID FROM DUAL;
SELECT fn_processcurrent INTO vPROCSESSID FROM DUAL;
OPEN c;
LOOP
FETCH c
BULK COLLECT INTO l_arr
LIMIT 500;
EXIT WHEN l_arr.COUNT = 0;
BEGIN
FOR r IN 1 .. l_arr.COUNT
LOOP
vprev (r).vPREVPERIODVALUE :=
'SELECT NVL (SUM (CURRPERIODVALUE), 0)
FROM LIQUIDATIONSDETAILS
WHERE APPOINTOFCAID = l_arr (r).ID
AND PROCESSID < vPROCSESSID
AND SUBSTR (PROCESSID, 5, 2) = 12
AND AUDITORID = 477';
END LOOP;
FORALL i IN 1 .. l_arr.COUNT
INSERT INTO liquidationsdetails (....)
VALUES (...);
EXCEPTION
WHEN DML_ERRORS
THEN
NULL;
END;
EXIT WHEN c%NOTFOUND;
END LOOP;
CLOSE C;
COMMIT;
END;
我想使用oracle bulk forall collect循环中的select语句将结果设置为数组变量。 在上面的代码中,我收到[错误]执行(60:42):PLS-00487:对变量'NUMBER'PL / SQL的无效引用:语句被忽略。
如果可能的话,我更喜欢在forall循环中使用SELECT SUM()语句。
有什么想法吗?
答案 0 :(得分:1)
在问题的代码中,您尝试将字符串分配给数字表中的元素;在你已经修改过的注释中选择一个数值,但是你们两个都没有表格元素引用错误;这样:
INTO vprev (r).vPREVPERIODVALUE
应该是:
INTO vprev (r)
vPREVPERIODVALUE
类型为vprev
(并且为TABLE OF NUMBER
),因此您不直接引用该类型。
在尝试为其元素赋值之前,您似乎也没有初始化或扩展该集合。
对光标循环的每次迭代执行单个选择似乎相当奇怪且效率低下无论如何;你可以在光标中进行外连接,例如:
CURSOR c
IS
SELECT vcn.ID, vcn.OAUDITORID,
NVL (SUM (CURRPERIODVALUE), 0) AS PREVPERIODVALUE
FROM view_cost_noabc vcn
LEFT JOIN LIQUIDATIONSDETAILS ld
ON ld.APPOINTOFCAID = vcn.ID
AND ld.AUDITORID = vcn.OAUDITORID
AND ld.PROCESSID < vPROCSESSID
AND SUBSTR (ld.PROCESSID, 5, 2) = 12
WHERE vcn.OAUDITORID = 477 AND vcn.FL <> 'Ο' AND vcn.yearid < 2015
GROUP BY vcn.ID, vcn.OAUDITORID
ORDER BY vcn.ID;
然后你根本不需要vPREVPERIODVALUE
,vprev
或你的内循环。您可能需要view_cost_noabc
中的其他列用于插入 - 如果是这样,请将它们添加到选择列表和group-by子句中。然后,您可以引用l_arr(i).PREVPERIODVALUE
来查看相应的值,因为它仍然基于游标的rowtype;并且我使用了左外连接,因为它看起来(基于NVL
),就像你在LIQUIDATIONSDETAILS
中不会总是有匹配的记录。
你没有显示表DDL,但由于vPROCSESSID
被声明为数字,PROCESSID
也可能是一个数字 - 在这种情况下使用substr
就是奇怪的 - 你正在隐式转换为字符串,并假设长度至少为7位。这可能对您和您的数据有意义,但看起来很奇怪。
目前forall
插入位于内环内部,这可能不是您真正想要的;但如果你失去了内循环,问题就会消失。