【问题标题】:Create Fucntion returning Table in pl/sql在 pl/sql 中创建函数返回表
【发布时间】:2021-08-30 13:56:17
【问题描述】:

TEMP表:

Node Curr_Cnt Prev_Cnt Diff
First 20 40 20
Second 30 70 40
CREATE OR REPLACE FUNCTION NEW_FUNCTION
RETURNS table
IS
    c_rec TEMP%ROWTYPE;
    TYPE c_tab IS TABLE OF c_rec%TYPE INDEX BY PLS_INTEGER;
    l_c_tab c_tab;

BEGIN
SELECT * INTO c_tab FROM

--**The below with clause starting from with returns the same table structure as above temp table**

( WITH batch_id_dtl AS
  (SELECT a.*,
    rownum rnum
  FROM
    (SELECT MIN(creation_date) min_cr,
      MAX(creation_date) max_cr,
      batch_id
    FROM oalterr.q_audit_results
    GROUP BY batch_id
    ORDER BY 1 DESC
    )a
    WHERE BATCH_ID <= 251940
  ),
  curr_cnt AS
 ......rest of the code......
);

RETURN C_TAB;

END NEW_FUNCTION;

上述函数返回如下错误:

表达式“C_TAB”不适合作为赋值语句的左侧。

谁能告诉我应该在返回部分添加什么类型以及在beginend之间的执行部分我做错了什么。

【问题讨论】:

  • 请更正您问题下方的标签(使用edit)。 plsql 与 Oracle 有关,注意与 mysql 有关,因此,当前的标签组合似乎不正确。
  • 另外,请不要标记PL/SQL Developer 之类的工具,除非问题是如何使用它们。

标签: oracle stored-procedures plsql plsqldeveloper stored-functions


【解决方案1】:

对于示例表(您发布的那个)

SQL> select * from temp;

NODE     CURR_CNT   PREV_CNT       DIFF
------ ---------- ---------- ----------
First          20         40         20
Second         30         70         40

在 SQL 级别创建类型,以便函数识别它:

SQL> create or replace type t_row as object
  2    (node        varchar2(10),
  3     curr_cnt    number,
  4     prev_cnt    number,
  5     diff        number);
  6  /

Type created.

SQL> create or replace type t_tab as table of t_row;
  2  /

Type created.

函数返回一个类型;例如,numbervarchar2 或 - 在你的情况下 - t_tab

SQL> create or replace function new_function
  2    return t_tab
  3  is
  4    l_tab t_tab;
  5  begin
  6    select t_row(node, curr_cnt, prev_cnt, diff)
  7      bulk collect
  8      into l_tab
  9      from temp;
 10    return l_tab;
 11  end new_function;
 12  /

Function created.

到目前为止一切顺利。现在,调用它。一种方法很简单,就像选择sysdate(也是一个函数):

SQL> select new_function from dual;

NEW_FUNCTION(NODE, CURR_CNT, PREV_CNT, DIFF)
--------------------------------------------------------------------------------
T_TAB(T_ROW('First', 20, 40, 20), T_ROW('Second', 30, 70, 40))

但这看起来有点难看。更好的方法是

SQL> select * from table(new_function);

NODE         CURR_CNT   PREV_CNT       DIFF
---------- ---------- ---------- ----------
First              20         40         20
Second             30         70         40

SQL>

【讨论】:

    【解决方案2】:

    最简单的方法是使用 PIPELINED 子句创建函数,然后在正文中,使用本机 PL/SQL 方法,在循环中遍历您的选择作为游标,并使用 PIPE ROW 返回每一行。

    另外,最好在一个包中声明返回类型和表函数,并避免泛型返回类型。

    办公室。然后你使用这样的功能

    从表中选择 *(package.function())

    另请参阅:https://docs.oracle.com/cd/B19306_01/appdev.102/b14289/dcitblfns.htm

    【讨论】:

      猜你喜欢
      • 2018-04-10
      • 2017-01-20
      • 1970-01-01
      • 2013-05-06
      • 2013-02-26
      • 1970-01-01
      • 1970-01-01
      • 2013-10-01
      • 2012-03-24
      相关资源
      最近更新 更多