Oracle SQL Developer,在函数中使用动态SQL

时间:2014-10-08 21:31:44

标签: sql oracle plsql oracle-sqldeveloper

我有以下脚本,其中包含名为'myFunction'的函数。 (名称为 rowValueTmp rowValueTable 的类型声明也附有您的信息)基本上,我需要使用表名作为 myFunction 。我发现我需要使用动态SQL才能使用表名作为参数(如果有其他方法可以帮我纠正)。因此,以下代码是我到目前为止所尝试的。

create or replace type rowValueTmp as object (
    month number,
    year number
);
/    
create or replace type rowValueTable as table of rowValueTmp;
/        
create or replace FUNCTION myFunction (TABLENAME in VARCHAR2) 
    return rowValueTable as
      v_ret   rowValueTable;
    begin
      execute immediate '
      select rowValueTmp(month, year)
      bulk collect into v_ret
      from '||TABLENAME;    
      return v_ret;
    end myFunction;
/
select * from table(myFunction('SCHEMA.TEST'));

但是,这段代码给了我一个错误,我认为是因为在立即执行块中使用“批量收集”而发生此错误。

ORA-03001: unimplemented feature

如果我将立即执行的内容替换为以下内容,则上述脚本正在运行..

select rowValueTmp(month, year)
bulk collect into v_ret
from SCHEMA.TEST;

问题
1]有没有办法(而不是动态SQL)我可以使用表名作为 myFunction 的输入参数?
2]如果我不允许在立即执行块中使用批量收集,您有什么建议?

1 个答案:

答案 0 :(得分:4)

您可以将execute immediately的值返回到bulk collect

CREATE OR REPLACE FUNCTION myfunction (tablename IN VARCHAR2)
   RETURN rowvaluetable AS
   v_ret rowvaluetable;
   v_table VARCHAR2 (61) := DBMS_ASSERT.sql_object_name (tablename);
BEGIN
   EXECUTE IMMEDIATE '
      select rowValueTmp(month, year)
      from ' || v_table
      BULK COLLECT INTO v_ret;

   RETURN v_ret;
END myfunction;
/

为了充分谨慎,我建议使用DBMS_ASSERT来验证表格参数(如图所示)。