包规范中定义的记录类型的Oracle函数返回表

包规范中定义的记录类型的Oracle函数返回表,oracle,plsql,oracle12c,Oracle,Plsql,Oracle12c,我有一个函数,它获取一个字符串和分隔符作为输入参数,并将拆分后的字符串作为表返回。 运行此函数时: create or replace PACKAGE split_pkg AS TYPE triplex_record IS RECORD ( id NUMBER, data VARCHAR2(4000), data1 VARCHAR2(4000), d

我有一个函数,它获取一个字符串和分隔符作为输入参数,并将拆分后的字符串作为表返回。 运行此函数时:

create or replace PACKAGE split_pkg AS
TYPE triplex_record IS RECORD (
                id      NUMBER,
                data    VARCHAR2(4000),
                data1   VARCHAR2(4000),
                data2   VARCHAR2(4000)
                );
TYPE triplex_tab IS TABLE OF triplex_record;
FUNCTION triplex (p_txt IN VARCHAR2, p_delimiter IN VARCHAR2) RETURN triplex_tab ;
END split_pkg;
/
create or replace PACKAGE BODY split_pkg AS
FUNCTION triplex (p_txt IN VARCHAR2, p_delimiter IN VARCHAR2)
    RETURN triplex_tab
AS
    triplex_tbl     triplex_tab := triplex_tab();
BEGIN
    FOR i IN 1..TRUNC((REGEXP_COUNT(p_txt , '[^' || p_delimiter || ']+'))/3)
    LOOP
        triplex_tbl.EXTEND;
        triplex_tbl(triplex_tbl.LAST).id := i;
        triplex_tbl(triplex_tbl.LAST).data := TRIM(REGEXP_SUBSTR(p_txt, '[^' || p_delimiter || ']+' , 1, 3 * i - 2));
        triplex_tbl(triplex_tbl.LAST).data1 := TRIM(REGEXP_SUBSTR(p_txt, '[^' || p_delimiter || ']+' , 1, 3 * i - 1));
        triplex_tbl(triplex_tbl.LAST).data2 := TRIM(REGEXP_SUBSTR(p_txt, '[^' || p_delimiter || ']+' , 1, 3 * i));
        --PIPE ROW(triplex_tbl);
    END LOOP;
    RETURN triplex_tbl;
END triplex;
END split_pkg;
我得到以下错误:

ORA-00902:无效的数据类型


如果将create作为一个流水线函数,我没有问题,我只想用RECORD TYPE在包的头中定义我的类型,而不是用create TYPE在模式级别定义我的类型。如何做到这一点?

没有看到软件包出现问题:

SET SERVEROUTPUT ON;

DECLARE
  triplets SPLIT_PKG.triplex_tab;
BEGIN
  triplets := split_pkg.triplex( 'a1,a2,a3,b1,b2,b3,c1,c2,c3,d1', ',' );
  FOR i IN 1 .. triplets.COUNT LOOP
    DBMS_OUTPUT.PUT_LINE( triplets(i).data );
    DBMS_OUTPUT.PUT_LINE( triplets(i).data1 );
    DBMS_OUTPUT.PUT_LINE( triplets(i).data2 );
    DBMS_OUTPUT.PUT_LINE( '------' );
  END LOOP;
END;
/
输出

anonymous block completed
a1
a2
a3
------
b1
b2
b3
------
c1
c2
c3
------
但是,如果希望在SQL中使用结果,则需要在SQL中而不是在包中定义类型

CREATE TYPE triplex_obj IS OBJECT (
  id      NUMBER,
  data    VARCHAR2(4000),
  data1   VARCHAR2(4000),
  data2   VARCHAR2(4000)
);

CREATE TYPE triplex_tab IS TABLE OF triplex_obj;

create or replace PACKAGE split_pkg AS
FUNCTION triplex (p_txt IN VARCHAR2, p_delimiter IN VARCHAR2) RETURN triplex_tab ;
END split_pkg;
/
SHOW ERRORS;

create or replace PACKAGE BODY split_pkg AS
FUNCTION triplex (p_txt IN VARCHAR2, p_delimiter IN VARCHAR2)
    RETURN triplex_tab
AS
    triplex_tbl     triplex_tab := triplex_tab();
BEGIN
    FOR i IN 1..TRUNC((REGEXP_COUNT(p_txt , '[^' || p_delimiter || ']+'))/3)
    LOOP
        triplex_tbl.EXTEND;
        triplex_tbl(triplex_tbl.LAST) := triplex_obj(
          i,
          TRIM(REGEXP_SUBSTR(p_txt, '[^' || p_delimiter || ']+' , 1, 3 * i - 2)),
          TRIM(REGEXP_SUBSTR(p_txt, '[^' || p_delimiter || ']+' , 1, 3 * i - 1)),
          TRIM(REGEXP_SUBSTR(p_txt, '[^' || p_delimiter || ']+' , 1, 3 * i - 0))
        );
    END LOOP;
    RETURN triplex_tbl;
END triplex;
END split_pkg;
/
SHOW ERRORS;
然后:

提供与上述相同的输出,但您也可以执行以下操作:

SELECT *
FROM   TABLE( split_pkg.triplex( 'a1,a2,a3,b1,b2,b3,c1,c2,c3,d1', ',' ) );
哪些产出:

id      Data    Data1   Data2
------- ------- ------- -------
1       a1      a2      a3
2       b1      b2      b3
3       c1      c2      c3

你从哪里得到的错误?在编译包体时?调用函数的时候?如何调用函数?@Justin Cave,包编译时没有任何错误,我在运行“SELECT*FROM TABLE(SPLIT_PKG.TRIPLEX('sample text',','));”时出错我怀疑你从这里到不了那里。这篇文章包含了一个非常好的选项摘要。根据您正试图完成的工作,可能有其他方法来构造代码(包括填充本地集合并将其传递给
函数),但很难猜测这些方法是否适用于您。我强烈建议您只在SQL中定义类型。@Justin Cave,如果我用“创建或替换类型…”来定义过程和函数中需要的所有类型,这会让人感到困惑,所以我想在它们的包头中定义每一个类型。这样的权衡是,您不能在纯SQL语句中使用它们。如果您的SQL语句位于PL/SQL块中,您可以定义集合类型的局部变量,调用函数填充该集合,然后稍后将该集合传递给
函数(这是12.1中的新功能)。非常感谢,我知道如果我在SQL级别定义类型,它将起作用,但是我不想在SQL级别上定义它们,我只需要在包头上定义它们,并且能够像…从表(…)中查询它们那样查询它们。你不能-如果你想在SQL中使用它们,你需要在SQL级别上定义
类型
s-如果你想在PL/SQL中使用它们,你可以在SQL或包(PL/SQL)级别上定义它们。
id      Data    Data1   Data2
------- ------- ------- -------
1       a1      a2      a3
2       b1      b2      b3
3       c1      c2      c3