Home » SQL & PL/SQL » SQL & PL/SQL » Aggregate operation on array (11.2.0.1.0)
Aggregate operation on array [message #676310] |
Thu, 30 May 2019 04:10 |
|
OraFerro
Messages: 433 Registered: July 2011
|
Senior Member |
|
|
Hi All,
I use a type to create a cursor and use this cursor to run a query and fill its data into an array of the same type.
I need to use this array multiple times, each time to do a different insert.
1- Op1 and Op2 (as per the below example) insert the needed data however they give a (ORA-01002: fetch out of sequence) and I need to understand why and how to avoid that.
3- For Op3 I have the option to close and reopen the cursor and reuse it to fill the array with aggregate data that I need to insert of learn if there is a way to reuse the first array to achieve this goal.
My test case:
create table test1
(
id number primary key,
value0 number
);
create table test2
(
id number,
value1 number,
value2 number,
fk_test1 number references test1(id)
);
insert all
INTO test1 values (1, 500)
INTO test1 values (2, 600)
INTO test1 values (3, 700)
INTO test1 values (4, 800)
INTO test1 values (5, 900)
INTO test2 values (1, 400, 70, 1)
INTO test2 values (2, 400, 70, 2)
INTO test2 values (3, 400, 70, 5)
INTO test2 values (4, 400, 70, 5)
INTO test2 values (5, 400, 70, 5)
select * from dual;
-- TESTPAC specification
CREATE OR REPLACE PACKAGE AFESD2.testPac AS
TYPE REC_COMtest IS RECORD
(
ID NUMBER(4),
value0 NUMBER(6),
value1 NUMBER(6),
value2 NUMBER(6)
);
-- Define cursor and table(array) of to hold COM CHARGE data
TYPE CUR_COMtest IS REF CURSOR RETURN REC_COMtest;
TYPE ARY_COMtest IS TABLE OF REC_COMtest;
PROCEDURE P_GET_DATA_TEST
(
I_NUM IN NUMBER,
MyCur OUT CUR_COMtest,
I_TOTAL_ROWS OUT NUMBER
);
end testpac;
CREATE OR REPLACE PACKAGE BODY AFESD2.testPac AS
PROCEDURE P_GET_DATA_TEST
(
I_NUM IN NUMBER,
MyCur OUT CUR_COMtest,
I_TOTAL_ROWS OUT NUMBER
)
AS
AR_MY_ARRAY ARY_COMtest;
I_total_sum number;
BEGIN
OPEN MyCur FOR
SELECT test1.id, value0, value1, value2
FROM test1, test2
WHERE test1.id = test2.FK_TEST1 ;
I_total_rows:=0;
--Op1: Normal fetch and use of ar_my_array to calculate a total value
FETCH MyCur BULK COLLECT INTO ar_My_Array;
FOR I IN 1..ar_My_Array.COUNT LOOP
I_total_rows := I_total_rows+ ( ar_My_Array(I).value0 + ar_My_Array(I).value1 * ar_My_Array(I).value2);
END LOOP;
FOR I IN 1..ar_My_Array.COUNT LOOP
INSERT INTO test1 (id, VALUE0)
SELECT 99+I , I_total_rows
FROM DUAL;
END LOOP;
I_total_sum :=0;
--Op2: resue the array to calculate an aggregate value I_total_sum and insert it
FOR I IN 1..ar_My_Array.COUNT LOOP
I_total_sum := I_total_sum + ar_My_Array(I).value2;
END LOOP;
INSERT INTO test1 (id, VALUE0)
SELECT 77 , I_total_sum
FROM DUAL;
--Op3: My main question, if there is a way to reuse the same array and get the needed resutl instead of running another query
-- CLOSE MyCur;
-- OPEN MyCur FOR
-- SELECT FK_TEST1, sum(value0), sum(value1), sum(value2)
-- FROM test1, test2
-- WHERE test1.id = test2.FK_TEST1
-- group by FK_TEST1;
--
-- FETCH MyCur BULK COLLECT INTO ar_My_Array;
-- FOR I IN 1..ar_My_Array.COUNT LOOP
-- INSERT INTO test1 (id, VALUE0)
-- SELECT 1000+I , ar_My_Array(I).value2
-- FROM DUAL;
-- END LOOP;
END;
end testPac;
Thanks,
Ferro
|
|
|
Goto Forum:
Current Time: Thu Apr 25 06:13:13 CDT 2024
|