Home » SQL & PL/SQL » SQL & PL/SQL » Loop after fetch on generic SYS_REFCURSOR (11.2.0.1.0)
|
|
|
|
Re: Loop after fetch on generic SYS_REFCURSOR [message #676177 is a reply to message #676174] |
Sun, 19 May 2019 04:45   |
 |
OraFerro
Messages: 433 Registered: July 2011
|
Senior Member |
|
|
Thanks Michel for your reply,
1- Please see the test case below.
2- One cursor carrying the select results and a variable that presents the sum of adding two variables and multiplying with the third.
3- .net C#
4- In the real case, there is no risk of data changes and the sum can be determined after the select.
In fact, in the real case, the sum is inserted is stored as parity to make sure that the data being inserted (same function is called to retrieve the data and parity) is similar to the data received in the first stage.
The actual data is an account statement which one user reviews and then sends a task for another user to approve and submit (insert). the two processes do not happen in the same time and the parity is used as a control.
create table test1
(
id number primary key,
value0 number
);
create table test2
(
id number,
value1 number,
value2 number,
fk_test1 number references test1(id)
);
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)
insert all
INTO test2 values (1, 400, 70, 1)
INTO test2 values (2, 400, 70, 2)
INTO test2 values (3, 400, 70, 3)
INTO test2 values (4, 400, 70, 4)
INTO test2 values (5, 400, 70, 5)
select * from dual;
CREATE OR REPLACE PROCEDURE P_GET_DATA_TEST
(
I_NUM IN NUMBER,
CUR_REF OUT SYS_REFCURSOR,
I_TOTAL_ROWS OUT NUMBER
)
AS
TYPE ARY_ARRAY IS TABLE OF SYS_REFCURSOR;
AR_MY_ARRAY ARY_ARRAY;
BEGIN
OPEN CUR_REF FOR
SELECT test1.id, value0, value1, value2
FROM test1, test2
WHERE test1.id = test2.FK_TEST1 ;
I_total_rows:=0;
FETCH CUR_REF 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;
/* instead of using another cursor and
OPEN CUR_ANOTHER_CURSOR FOR
SELECT sum( value0+ value1* value2 ) into I_total_rows
FROM test1, test2
WHERE test1.id = test2.FK_TEST1 ;
*/
CLOSE CUR_REF;
END;
Thanks,
Ferro
|
|
|
Re: Loop after fetch on generic SYS_REFCURSOR [message #676178 is a reply to message #676177] |
Sun, 19 May 2019 06:56   |
 |
Michel Cadot
Messages: 68758 Registered: March 2007 Location: Saint-Maur, France, https...
|
Senior Member Account Moderator |
|
|
Quote:4- In the real case, there is no risk of data changes and the sum can be determined after the select.
So you don't need the sum to be computed by the procedure, you can do it in the client program itself as you do it in your example procedure.
You can also do it in the following way:
SQL> select * from test1;
ID VALUE0
---------- ----------
1 500
2 600
3 700
4 800
5 900
5 rows selected.
SQL> select * from test2;
ID VALUE1 VALUE2 FK_TEST1
---------- ---------- ---------- ----------
1 400 70 1
2 400 70 2
3 400 70 3
4 400 70 4
5 400 70 5
5 rows selected.
SQL> CREATE OR REPLACE PROCEDURE P_GET_DATA_TESTCUR_REF (CUR_REF OUT SYS_REFCURSOR)
2 AS
3 BEGIN
4 OPEN CUR_REF FOR
5 SELECT test1.id, value0, value1, value2,
6 sum( value0+ value1* value2 ) over () TOTAL
7 FROM test1, test2
8 WHERE test1.id = test2.FK_TEST1 ;
9 END;
10 /
Procedure created.
SQL> var c refcursor
SQL> exec P_GET_DATA_TESTCUR_REF (:c)
PL/SQL procedure successfully completed.
SQL> print c
ID VALUE0 VALUE1 VALUE2 TOTAL
---------- ---------- ---------- ---------- ----------
1 500 400 70 143500
2 600 400 70 143500
3 700 400 70 143500
4 800 400 70 143500
5 900 400 70 143500
5 rows selected.
You get the total on the first fetch (and any subsequent one) instead of an OUT parameter of the procedure.
|
|
|
|
|
|
|
Goto Forum:
Current Time: Fri Jun 06 03:57:34 CDT 2025
|