My Question is "How can we return multiple records from pl/sql stored procedure without taking OUT parameter".I got this doubt because if we are using cursors or refcursor in out parameter it may degrade performance.So what is the solution??
Asked
Active
Viewed 251 times
-3
-
You could populate an array I suppose, but that is likely to perform worse than a cursor. You can have [an implicit cursor](https://stackoverflow.com/a/40360471/230471) to avoid declaring one, but it's still a cursor. – William Robertson Apr 19 '18 at 16:20
-
1What evidence do you have that it will degrade performance? – OldProgrammer Apr 19 '18 at 16:37
-
That's not really *returning* anything, but - you could populate some table with that stored procedure, and then - somewhere else (in a report, for example) select data stored in that table. – Littlefoot Apr 19 '18 at 17:53
1 Answers
1
As OldProgrammer wrote, i think the performance of a cursor wouldn't be you problem. But here a Solution anyway:
You can return custom types like Table of number
. If it's only a list of numbers you could return a table of numbers
. If you Want to return rows from a table you could return table of 'tablename'%ROWTYPE
. But i guess you want to create some custom types.
CREATE OR REPLACE TYPE PUWB_INT.MyOrderType AS OBJECT
(
OrderId NUMBER,
OrderName VARCHAR2 (255)
)
/
CREATE OR REPLACE TYPE PUWB_INT.MyOrderListType AS TABLE OF MYORDERtype
/
Now we can use them similar to a return myNumberVariable;
Let's build a function (procedures don't have return values):
CREATE OR REPLACE FUNCTION PUWB_INT.MyFunction (SomeInput VARCHAR2)
RETURN MyOrderListType
IS
myOrderList MyOrderListType := MyOrderListType ();
BEGIN
FOR o IN (SELECT 1 AS Id, 'One' AS Name FROM DUAL
UNION ALL
SELECT 2 AS Id, 'Two' AS Name FROM DUAL)
LOOP
myOrderList.EXTEND ();
myOrderList (myOrderList.COUNT) := MyOrderType (o.Id, o.Name || '(' || SomeInput || ')');
END LOOP;
RETURN myOrderList;
END MyFunction;
/
Now we can call the function and get a table of our custom-type:
DECLARE
myOrderList MyOrderListType;
myOrder MyOrderType;
BEGIN
myOrderList := MyFunction ('test');
FOR o IN myOrderList.FIRST .. myOrderList.LAST
LOOP
myOrder := myOrderList (o);
DBMS_OUTPUT.put_line ('Id: ' || myOrder.OrderId || ', Name: ' || myOrder.OrderName);
END LOOP;
END;
Be aware, that the calling schema, has to know the type.
![](../../users/profiles/4340461.webp)
kara
- 2,942
- 4
- 16
- 29