DDL for Package specification
create or replace PACKAGE POLYMORPHIC_PKG AS
FUNCTION describe (tab IN OUT DBMS_TF.table_t)
RETURN DBMS_TF.describe_t;
PROCEDURE fetch_rows;
END POLYMORPHIC_PKG;
Package created.
DDL for Package body
create or replace PACKAGE BODY POLYMORPHIC_PKG AS
g_theCursor integer default dbms_sql.open_cursor;
function evaluate_expression
( p_expression in varchar2)
return number
is
l_rowsprocessed number default 0;
l_retval number;
begin
dbms_sql.parse(g_theCursor,
'begin :ret_val := ' || p_expression ||
'; end;',
dbms_sql.native );
dbms_sql.bind_variable ( g_theCursor,':ret_val',l_retval );
l_rowsprocessed := dbms_sql.execute(g_theCursor);
dbms_sql.variable_value ( g_theCursor, ':ret_val', l_retval );
return l_retval;
end evaluate_expression;
FUNCTION describe (tab IN OUT DBMS_TF.table_t)
RETURN DBMS_TF.describe_t
AS
BEGIN
-- Make sure the for_read flag for each real column is set, or get_row_set has no values.
FOR i IN 1 .. tab.column.count LOOP
CONTINUE WHEN NOT DBMS_TF.supported_type(tab.column(i).description.TYPE);
tab.column(i).for_read := TRUE;
END LOOP;
-- Add the new RESULT column.
RETURN DBMS_TF.describe_t(
new_columns => DBMS_TF.columns_new_t(1 => DBMS_TF.column_metadata_t(name =>'RESULT'))
);
END;
PROCEDURE fetch_rows AS
l_row_set DBMS_TF.row_set_t;
l_new_col DBMS_TF.tab_varchar2_t;
l_row_count PLS_INTEGER;
l_putcolcount pls_integer;
v_temp_var varchar2(500) := 'A';
env dbms_tf.env_t := dbms_tf.get_env();
BEGIN
DBMS_TF.get_row_set(l_row_set, l_row_count, l_putcolcount);
FOR row_num IN 1 .. l_row_count LOOP
for colindx in 1 .. env.get_columns.count loop
IF env.get_columns ( colindx ).name = '"EXPRESSION"' then
v_temp_var := nvl(l_row_set(colindx).tab_varchar2 (row_num), 'empty');
else
v_temp_var := REPLACE(v_temp_var, REPLACE(env.get_columns ( colindx ).name, '"', ''), nvl(l_row_set(colindx).tab_number (row_num), '0'));
end if;
end loop;
-- Populate the new column with the result of the associated row.
l_new_col(row_num) := evaluate_expression(v_temp_var);
END LOOP;
-- Associate the new values with the new column.
DBMS_TF.put_col(1, l_new_col);
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
END POLYMORPHIC_PKG;
Package Body created.
3. DDL for Function MY_POLYMORPHIC_TABLE
CREATE OR REPLACE FUNCTION MY_POLYMORPHIC_TABLE (tab IN TABLE)
RETURN TABLE PIPELINED
ROW POLYMORPHIC
USING POLYMORPHIC_PKG;
Function created.
4. Demo
with my_set as (
select 'VAR1+VAR2*VAR3/TEST1' expression, 24 var1, 30 var2, 15 var3, 450 test1 from dual
union all
select 'VAR1+VAR2/VAR3+TEST1' expression, 24 var1, 30 var2, 15 var3, 1 test1 from dual
union all
select 'VAR1+POWER(VAR2,VAR3)' expression, 2 var1, 2 var2, 2 var3, 27/3 test1 from dual
union all
select '1/(VAR1/POWER(VAR2,VAR3))' expression, 4 var1, 2 var2, 2 var3, 3*3 test1 from dual
)
SELECT *
FROM MY_POLYMORPHIC_TABLE(my_set)
EXPRESSION | VAR1 | VAR2 | VAR3 | TEST1 | RESULT | VAR1+VAR2*VAR3/TEST1 | 24 | 30 | 15 | 450 | 25 | VAR1+VAR2/VAR3+TEST1 | 24 | 30 | 15 | 1 | 27 | VAR1+POWER(VAR2,VAR3) | 2 | 2 | 2 | 9 | 6 | 1/(VAR1/POWER(VAR2,VAR3)) | 4 | 2 | 2 | 9 | 1 |
---|