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
.)