我有一个函数,它获取一个字符串和分隔符作为输入参数,并将分割的字符串作为表返回。 当我运行这个功能时:
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:数据类型无效
如果创建为PIPELINED函数我没有问题,我只想在PACKAGE'标题中使用RECORD TYPE定义我的TYPE,而不是在模式级别使用CREATE TYPE。怎么办?
答案 0 :(得分:1)
没有看到包的问题:
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;
然后:
SET SERVEROUTPUT ON;
DECLARE
triplets 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;
/
提供与上面相同的输出,但您也可以这样做:
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