简体   繁体   English

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

[英]Oracle SQL Developer, using dynamic SQL in function

I have the following script which contains a function named 'myFunction' . 我有以下脚本,其中包含一个名为'myFunction'的函数。 (declaration of types named rowValueTmp and rowValueTable are also attached for your information) Basically, I need to use a table name as an input parameter for myFunction . (还附带了名为rowValueTmprowValueTable的类型声明,以供您参考)基本上,我需要使用表名作为myFunction的输入参数。 I found that I need to use dynamic SQL in order to use the table name as a parameter (Please correct me if there are alternative ways to do this). 我发现我需要使用动态SQL才能将表名用作参数(如果有其他替代方法,请更正我)。 So the following code is what I have tried so far. 因此,以下代码是到目前为止我尝试过的代码。

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'));

But, this code gives me an error, and I assumed that this error is occurred because of using ' bulk collect ' in execute immediate block. 但是,这段代码给了我一个错误,并且我假定发生此错误是因为在执行立即执行块中使用了“ 批量收集 ”。

ORA-03001: unimplemented feature

If I replace the content of execute immediate as the following, the above script is working.. 如果按以下方式替换立即执行的内容,则上述脚本正在工作。

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

Question
1] Is there any way(rather than Dynamic SQL) that I can use a table name as an input parameter for myFunction ? 1]有什么方法(而不是Dynamic SQL)可以将表名用作myFunction的输入参数?
2] If I am not allowed to use bulk collect in execute immediate block, what do you suggest? 2]如果不允许在执行立即执行块中使用批量收集 ,您有什么建议?

You can return values from execute immediately into a bulk collect : 您可以将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;
/

In the interest of an abundance of caution, I'd recommend using DBMS_ASSERT to validate the table parameter as well (as shown). DBMS_ASSERT谨慎考虑,我建议也使用DBMS_ASSERT来验证表参数(如图所示)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM