There are at least three ways to do this: 1) CCreate a nested table 2) Call the function multiple times 3) Create a function to access each attribute.
Sample objects
create or replace type myType as object
(
wx number,
xy number
);
CREATE OR REPLACE FUNCTION f_myFunction
(
myId IN RAW := NULL
) RETURN myType
AS
ResultTable myType := myType(1, 2);
BEGIN
RETURN ResultTable;
END;
/
Method 1: Create a nested table
As Luke Woodward pointed out, the features TABLE and CAST require a nested table of types. Even if you only intend to use a single element.
create or replace type myType_nt is table of myType;
CREATE OR REPLACE FUNCTION f_myFunction_nt
(
myId IN RAW := NULL
) RETURN myType_nt
AS
ResultTable myType_nt := myType_nt(myType(1, 2));
BEGIN
RETURN ResultTable;
END;
/
select wx, xy from table(f_myFunction_nt());
WX XY
-- --
1 2
Method 2: Repeat the function call for each attribute
Extra objects are unnecessary if the function is called once for each attribute. This is repetitive and potentially costly. Setting the function to deterministic may prevent the function from actually being called multiple times.
select wx, xy from
(
select f_myFunction().wx wx, f_myFunction().xy xy from dual
);
WX XY
-- --
1 2
It seems like there should be an easier way to do this. Oracle does support calling the function once and returning the type with both attributes. But there is no way to meaningfully use that type. The attributes are not easily accessible from SQL.
SQL> select * from (select f_myFunction() from dual);
F_MYFUNCTION()(WX, XY)
-----------------------------------------------------
MYTYPE(1, 2)
The intuitive way, simply using each attribute name, does not work.
SQL> select wx, xy from (select f_myFunction() from dual);
select wx, xy from (select f_myFunction() from dual)
*
ERROR at line 1:
ORA-00904: "XY": invalid identifier
Method 3: Create a function for each attribute
You can access the attributes with a function. This requires adding new objects but it keeps your main function the same.
create or replace function get_wx(p_myType myType) return number is
begin
return p_myType.wx;
end;
/
create or replace function get_xy(p_myType myType) return number is
begin
return p_myType.xy;
end;
/
select get_wx(asdf) wx, get_xy(asdf) xy
from (select f_myFunction() asdf from dual);
WX XY
-- --
1 2