Table Functions, Direct Database Requests, and NUMBER data types
706739Jun 15 2009 — edited Jul 7 2009Hello. I call a number of table functions from our BI Enterprise server, and I've elected to do so using Direct Database Requests (I believe you can also call table functions in the physical layer of the repository, but that's not what I'm doing). The problem is that whenever I return any number from the table function that is not a whole number (1.23, for example), BI assigns the INTEGER datatype to the field instead of the DOUBLE datatype, thereby rounding my number to the nearest integer. Here's a concise example:
Create these 3 database objects:
CREATE OR REPLACE TYPE my_row AS OBJECT (my_num NUMBER);
CREATE OR REPLACE TYPE my_tab AS TABLE OF my_row;
CREATE OR REPLACE FUNCTION my_table_function RETURN my_tab
PIPELINED IS
BEGIN
PIPE ROW(my_row(1.23));
END;
/
Then make this your query in your Direct Database Request:
SELECT my_num FROM table(my_table_function);
That query correctly returns "1.23" when it's called from the database. In BI, on the other hand, it returns "1" (and labels the field an INTEGER instead of DOUBLE data type). If in the Direct Database Request you change the Column Properties ->Data Format -> Decimal Places from 0 to 2, it then not surprisingly displays "1.00". I then tried changing MY_ROW.MY_NUM's datatype by explicitly specifying precision, and no luck. BI still labels this field as an INTEGER. Then I started trying to trick BI by massaging the SQL statement itself. None of the following worked:
SELECT to_number(my_num) as my_num2 FROM table(my_table_function);
SELECT my_num2 + 0.01 as my_num3 FROM (SELECT my_num - 0.01 AS my_num2 FROM table(my_table_function));
SELECT to_number(to_char(my_num)) as my_num2 FROM table(my_table_function);
SELECT to_number(substr(to_char('x'||my_num),2)) as my_num2 FROM table(my_table_function);
Now I did find a solution, but I'm surprised that I have to resort to this:
SELECT * FROM (SELECT /*+ NO_MERGE */ my_num FROM table(my_table_function));
Does anyone out there know of a better way to do this? The above is a hack in my opinion. :)
Thanks in advance for any input.
-Jim