从 Oracle 函数返回一个表,在匿名块中定义

Posted

技术标签:

【中文标题】从 Oracle 函数返回一个表,在匿名块中定义【英文标题】:Returning a Table from an Oracle function, defined within an anonymous block 【发布时间】:2014-10-08 17:06:34 【问题描述】:

我有一个这样的 DECLARE 块

DECLARE
  TYPE WordList IS TABLE OF VARCHAR2(50);

  FUNCTION getWordList
    RETURN WordList
  IS
    words WordList := WordList();  
  BEGIN
    words.EXTEND;
    words(1) := 'aardvark';
    RETURN words;
  END;

BEGIN
  SELECT * FROM TABLE(getWordList);

END;
/

当我尝试从 sqlplus 运行它时,我得到了这个......

ERROR at line 15:
ORA-06550: line 15, column 23:
PLS-00231: function 'GETWORDLIST' may not be used in SQL
ORA-06550: line 15, column 23:
PL/SQL: ORA-00904: "GETWORDLIST": invalid identifier
ORA-06550: line 15, column 3:
PL/SQL: SQL Statement ignored

似乎如果我要在匿名块之外定义函数,那么它可以正常工作,但我试图避免这种情况,因为我想针对实时数据库运行一些函数,我不想这样做在脚本运行时实时创建和删除函数。如果我只在匿名函数中定义事物,那么我没有任何清理工作要做。

我要做的是编写一个函数,该函数将返回一个结果列表(以任何形式、集合、光标,我不挑剔),然后我可以将其传递给另一个函数以进行进一步处理。函数可能很复杂,我希望在将来重用它们,因此编写函数而不是在单个 SQL 语句中编写所有内容。

我是 Oracle 的新手,所以我试图找到符合规律而不是违背规律的习语和工作方式。

【问题讨论】:

【参考方案1】:

FunctionType 必须在 Oracle 中全局可用,才能在 SQL 中使用..

任何SELECT 实际上都会将上下文发送到 SQL 引擎并在那里执行查询。将结果发送回 PL/SQL 引擎..

只需PL/SQL 调用例如: 没有SQLs 的普通逻辑,您的方法将起作用..

所以下面需要做..

将类型创建为 SQL 对象。

CREATE TYPE WordList IS TABLE OF VARCHAR2(50);

声明函数

  CREATE FUNCTION getWordList
    RETURN WordList
  IS
    words WordList := WordList();  
  BEGIN
    words.EXTEND;
    words(1) := 'aardvark';
    RETURN words;
  END;
  /

然后调用它

BEGIN
  SELECT * INTO SOMERECORD FROM TABLE(getWordList);
END;
/

【讨论】:

这就是我试图避免做的事情。在这种情况下可能是不可能的,在这种情况下,我正在寻找替代策略来做我想做的事情。 是的,我明白您在寻找什么。这是不可能的,因为 SQL 需要在全局范围内定义它。您可以尝试将所有 FUNCTIONTYPE 声明放入脚本中。还有调用者块。它出现为单个本地声明。但是 Oracle 12c 带来了一些像这样的不错的特性。但我不确定。

以上是关于从 Oracle 函数返回一个表,在匿名块中定义的主要内容,如果未能解决你的问题,请参考以下文章

oracle存储过程匿名块函数包

无法在 Oracle 匿名块中调用和执行 .sql 脚本文件

内置函数与匿名函数

Oracle 匿名 PL/SQL 块中缺少关键字错误

在 Apply 块中使用需要表参数的标量函数

在 PL/SQL 中显示函数