【问题标题】:PLS-00201 Error in Pipelined Function in PL/SQLPLS-00201 PL/SQL 中流水线函数中的错误
【发布时间】:2021-04-06 12:33:34
【问题描述】:

我试图在 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)));

【问题讨论】:

  • IDS_T 类型的定义是什么,是否在同一个架构(所有者)中?
  • IDS_T 是一种表类型,它在同一个模式和所有者中

标签: plsql oracle18c pipelined-function


【解决方案1】:

正如你所说,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>

【讨论】:

  • 在您的 cmets 之后用更改更新了问题。请问您能帮忙解决错误吗?
  • 你没注意我写的。此行应该是pipe row (tf_row(to_number(substr(ids_in, n_start+1, n_end - n_start - 1))));,即您错过了使用 TF_ROW。
  • 使用 TF_ROW 解决了错误。创建了另一个函数来检索从流水线行传递的 ID 的名称。面临以下错误。创建或替换函数 func_ename (ids t_tab) RETURN VARCHAR2 IS l_tmp VARCHAR2(100); l_result VARCHAR2(400);开始 l_result := ';'; FOR i IN ids.first..ids.last LOOP SELECT l.evalue INTO l_tmp FROM listname l WHERE l.id = ids(i); l_result := l_result || l_tmp|| ';';结束循环;返回 l_result; END;/ 错误:PL/SQL:ORA-00932:不一致的数据类型:预期 NUMBER 得到 TF_ROW
  • WHERE 子句错误。我编辑了我的答案并添加了有效的代码。看看吧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多