简体   繁体   English

oracle在oracle bulk forall collect循环中添加select语句

[英]oracle add select statement in oracle bulk forall collect loop

I have the following plsql statement: 我有以下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;

I want to set the results using a select statement in oracle bulk forall collect loop to a array variable. 我想使用oracle bulk forall collect循环中的select语句将结果设置为数组变量。 In the above code I receive [Error] Execution (60: 42): PLS-00487: Invalid reference to variable 'NUMBER' PL/SQL: Statement ignored. 在上面的代码中,我收到[错误]执行(60:42):PLS-00487:对变量NUMBER的引用无效PL / SQL:语句被忽略。

I prefer to use the SELECT SUM () statement in forall loop if is it possible. 如果可能,我更喜欢在forall循环中使用SELECT SUM()语句。

Any idea? 任何想法?

In the code in the question you're trying to assign a string to an element in a table of numbers; 在问题的代码中,您尝试将字符串分配给数字表中的元素; in the comments you've modified that to select a numeric value, But in both you've got the table element reference wrong; 在注释中,您已经修改了它以选择一个数字值,但是在两种方法中,您都错误地引用了table元素; this: 这个:

INTO vprev (r).vPREVPERIODVALUE

should just be: 应该只是:

INTO vprev (r)

The vPREVPERIODVALUE is the type of vprev (and is TABLE OF NUMBER ), so you don't refer to that type directly. vPREVPERIODVALUE是类型vprev (并且是TABLE OF NUMBER ),这样你就不会直接引用该类型。

You also don't seem to be initialising or extending that collection before trying to assign values to its elements. 您似乎也没有在尝试向其元素分配值之前初始化或扩展该集合。

Doing a single select for each iteration of the cursor loop seems rather odd and inefficient anyway; 无论如何,对游标循环的每次迭代进行一次选择似乎很奇怪且效率低下。 you could do an outer join in the cursor instead, something like: 您可以在游标中进行外部联接,例如:

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;

Then you don't need vPREVPERIODVALUE , vprev or your inner loop at all. 然后,您根本不需要vPREVPERIODVALUEvprev或您的内部循环。 You may need other columns from view_cost_noabc for your insert - if so add them to the select list and the group-by clause. 您可能需要view_cost_noabc其他列进行插入-如果这样,请将其添加到选择列表和group-by子句中。 You can then refer to l_arr(i).PREVPERIODVALUE to see the corresponding value, since that's still based on the cursor's rowtype; 然后,您可以引用l_arr(i).PREVPERIODVALUE来查看相应的值,因为该值仍基于游标的行类型; and I've used a left outer join because it looks (based on the NVL ) like you won't always have matching records in LIQUIDATIONSDETAILS . 并且我使用了左外部LIQUIDATIONSDETAILS因为它看起来(基于NVL )看起来像您在LIQUIDATIONSDETAILS不会总是有匹配的记录。

You haven't shown the table DDL, but since vPROCSESSID is declared as a number it's likely the PROCESSID is also a number - in which case using substr on it is strange - you're doing an implicit conversion to a string, and assuming the length is at least 7 digits. 您尚未显示表DDL,但是由于vPROCSESSID被声明为数字,所以PROCESSID可能也是数字-在这种情况下,使用substr很奇怪-您正在隐式转换为字符串,并假定长度至少为7位数字。 This may make sense for you and your data but just looks odd. 这对您和您的数据可能有意义,但看起来很奇怪。

At the moment the forall insert is inside the inner loop which is not likely to be what you really intended; 此刻的forall插入是内循环这是不太可能是你真的打算内; but if you lose the inner loop that problem will go away anyway. 但是,如果您丢失了内部循环,该问题将始终消失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM