I currently have a table function that returns a table of data. This data is retrieved by 7 functions within and are all called as values in a row, which is then repeated I number of times to create a table of the rows of data. Everything works as needed when there are 12 items I need to retrieve data for. The problem is that there is a maximum number of 12 items, but at some locations the number of items changes. This causes my function to return 0 rows instead of either 12 rows with all null rows where there is no data, or only the rows with data and exclude the null rows. Either output would work.
I have tried incorporating a function that returns the count of items at the location to use as the limit for my for loop such as:
FOR i IN 0 .. get_COUNT(LOCATION) LOOP
This worked for the locations with items in order starting at I=0. This does not work for some locations where the first item is not in I=0. For example, one location has only one item in I=1. If I take out the loop and just run this function on I=1 I get the row. When I run the function, because the first row (I=0) returns all null, I get no table.
CREATE TYPE TEMPROW AS OBJECT(
VAL1 VARCHAR2(5),
VAL2 VARCHAR2(5),
VAL3 VARCHAR2(5),
VAL4 VARCHAR2(5),
VAL5 VARCHAR2(5),
VAL6 VARCHAR2(5),
VAL7 VARCHAR2(5));
CREATE TYPE TABTYPE AS TABLE OF TEMPROW;
CREATE OR REPLACE FUNCTION get_VALUES_TABLE (LOCATION IN VARCHAR2) RETURN TABLE AS
TEMPTAB TABTYPE := TABTYPE();
BEGIN
FOR I IN 0 .. 11 LOOP
TEMPTAB.EXTEND;
TEMPTAB(TEMPTAB.LAST) := TEMPROW(
get_VALUE(LOCATION,1,I),
get_VALUE(LOCATION,2,I),
get_VALUE(LOCATION,3,I),
get_VALUE(LOCATION,4,I),
get_VALUE(LOCATION,5,I),
get_VALUE(LOCATION,6,I),
get_VALUE(LOCATION,7,I));
END LOOP;
RETURN TEMPTAB;
END;
Advertisement
Answer
Of course it is possible. Here is a small example. Showing the server output only for the test query at the end.
drop type my_table_type
/
drop type my_row_type
/
create or replace type my_row_type as object(id number, str varchar2(10), dt date)
/
create or replace type my_table_type as table of my_row_type
/
create or replace function my_function(num_rows integer) return my_table_type
as
l_tab my_table_type := my_table_type();
begin
for i in 1 .. num_rows
loop
l_tab.extend;
l_tab(l_tab.last) := my_row_type(null, null, null);
end loop;
return l_tab;
end;
/
select rownum, t.* from table(my_function(3)) t;
ROWNUM ID STR DT
---------- ---------- ---------- ----------
1
2
3
(I added ROWNUM so we can see what’s happening; of course, you can just select * from table(my_function(3)), that is what will give the output where all the rows are null, null, null.)