0

我试图在 PL/SQL 中创建流水线表函数,但遇到以下错误。这是语法错误吗?

CREATE OR REPLACE FUNCTION FUNC_IDS(
    IDS_IN IN VARCHAR2
) RETURN IDS_T
    PIPELINED
IS

BEGIN
 
select * from dual;  
    return;

END func_ids;

脚本输出:

Function FUNC_IDS compiled 

LINE/COL  ERROR
--------- -------------------------------------------------------------
0/0       PL/SQL: Compilation unit analysis terminated

3/10      PLS-00201: identifier 'IDS_T' must be declared
Errors: check compiler log

我错过了在创建函数之前创建行和表类型。稍后创建了它们,如下所示,并尝试创建将输入作为 ID 字符串并将各个 ID 输出到另一个函数的函数。

CREATE TYPE TF_ROW AS OBJECT (ID NUMBER);

CREATE TYPE IDS_T IS TABLE  OF TF_ROW;

create or replace function func_ids (ids_in in varchar2) return ids_t pipelined is
  n_start      pls_integer := 1;
  n_end        pls_integer := 1;
--
begin
  
  loop
    -- find the first and next comma in string
    n_start := instr(ids_in, ',', n_start, 1);
    n_end   := instr(ids_in, ',', n_start, 2);
    --
    if (n_end <= 0) then
        exit;
    end if;

    -- get the string and pipe it back out
    pipe row (to_number(substr(ids_in, n_start+1, n_end - n_start - 1)));
    -- ready for next one
    n_start := n_end;
  end loop;
  return;
end func_ids;


Script Output:

Function FUNC_IDS compiled

LINE/COL  ERROR
--------- -------------------------------------------------------------
22/5      PL/SQL: Statement ignored
22/15     PLS-00382: expression is of wrong type
Errors: check compiler log

这里的表达有什么问题?pipe row (to_number(substr(ids_in, n_start+1, n_end - n_start - 1)));

4

1 回答 1

0

正如你所说,IDS_T没有宣布。

这是一个有效的例子。看看我是怎么做的,用你的数据自己做。

类型:

SQL> create or replace type t_row is object (empno number, ename varchar2 (20));
  2  /

Type created.

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

Type created.

功能:

SQL> create or replace function func_ids (ids_in in varchar2)
  2     return t_tab
  3     pipelined
  4  is
  5  begin
  6     for cur_r in (select empno, ename
  7                     from emp
  8                    where deptno = ids_in)
  9     loop
 10        pipe row (t_row (cur_r.empno, cur_r.ename));
 11     end loop;
 12
 13     return;
 14  end func_ids;
 15  /

Function created.

测试:

SQL> select * from table(func_ids (20));

     EMPNO ENAME
---------- --------------------
      7369 SMITH
      7566 JONES
      7788 SCOTT
      7876 ADAMS
      7902 FORD

SQL>

如何使用返回的结果FUNC_IDS?我正在使用您作为评论发布的代码(FUNC_ENAME函数)来做这件事;我标记了你做错了什么。

SQL> CREATE OR REPLACE FUNCTION func_ename (ids t_tab)
  2     RETURN VARCHAR2
  3  IS
  4     l_tmp     VARCHAR2 (100);
  5     l_result  VARCHAR2 (400);
  6  BEGIN
  7     l_result := ';';
  8
  9     FOR i IN ids.FIRST .. ids.LAST
 10     LOOP
 11        SELECT l.ename
 12          INTO l_tmp
 13          FROM emp l
 14         WHERE l.empno = ids (i).empno;         --> this line was wrong
 15
 16        l_result := l_result || l_tmp || ';';
 17     END LOOP;
 18
 19     RETURN l_result;
 20  END;
 21  /

Function created.

SQL> SELECT func_ename (func_ids (10)) FROM DUAL;

FUNC_ENAME(FUNC_IDS(10))
------------------------------------------------------------------
;CLARK;KING;MILLER;

SQL>
于 2021-04-06T13:05:01.053 回答