【问题标题】:Oracle SQL Developer, using dynamic SQL in functionOracle SQL Developer,在函数中使用动态 SQL
【发布时间】:2014-12-03 16:46:45
【问题描述】:

我有以下脚本,其中包含一个名为 'myFunction' 的函数。 (还附上了名为 rowValueTmprowValueTable 的类型声明以供您参考)基本上,我需要使用表名作为 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'));

但是,这段代码给了我一个错误,我认为这个错误是因为在 execute immediate 块中使用了“bulk collect”。

ORA-03001: unimplemented feature

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

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

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

【问题讨论】:

标签: sql oracle plsql oracle-sqldeveloper


【解决方案1】:

您可以将值从 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 来验证表参数(如图所示)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 2014-12-02
    • 2012-10-19
    相关资源
    最近更新 更多