PL/SQL函数return自定义类型异常
PL/SQL Function return custom type exception
我创建了一个包,其中包含一个自定义类型和一个 returns 自定义类型的函数,如下所示;
create or replace
PACKAGE INHOUSE_CUST_API
AS
TYPE doc_rec
IS
RECORD
(
doc_Title doc_issue_reference.title%Type,
doc_Number DOC_ISSUE_REFERENCE.DOC_NO%TYPE,
doc_Type DOC_ISSUE_REFERENCE.FILE_TYPE%TYPE,
doc_FileName DOC_ISSUE_REFERENCE.FILE_NAME%TYPE,
doc_Path DOC_ISSUE_REFERENCE.PATH%TYPE);
FUNCTION Get_Budget_Doc(
company IN VARCHAR2,
budget_process_id IN VARCHAR2,
budget_ptemplate_id IN VARCHAR2)
RETURN doc_rec;
END INHOUSE_CUST_API;
之后,我创建了如下函数体
create or replace
PACKAGE BODY INHOUSE_CUST_API
AS
FUNCTION Get_Budget_Doc(
company IN VARCHAR2,
budget_process_id IN VARCHAR2,
budget_ptemplate_id IN VARCHAR2)
RETURN doc_rec
IS
enhDocItem ENHANCED_DOC_REFERENCE_OBJECT%ROWTYPE;
docIssueRef DOC_ISSUE_REFERENCE%ROWTYPE;
docKeyValue VARCHAR2(150);
docIssueRef_rec doc_rec;
BEGIN
docKeyValue := company||'^'||budget_process_id||'^'||budget_ptemplate_id||'^';
--dbms_output.put_line(docKeyValue);
SELECT *
INTO enhDocItem
FROM ENHANCED_DOC_REFERENCE_OBJECT
WHERE KEY_VALUE= docKeyValue;
SELECT *
INTO docIssueRef
FROM DOC_ISSUE_REFERENCE
WHERE DOC_NO = enhDocItem.DOC_NO;
docIssueRef_rec.doc_Title :=docIssueRef.Title;
docIssueRef_rec.doc_Number:=docIssueRef.DOC_NO;
docIssueRef_rec.doc_Type :=docIssueRef.FILE_TYPE;
docIssueRef_rec.doc_Path :=docIssueRef.PATH;
RETURN docIssueRef_rec;
END Get_Budget_Doc;
END INHOUSE_CUST_API;
当我尝试像这样调用函数时
select INHOUSE_CUST_API.Get_Budget_Doc('param1','param2','param3') 来自 dual;
我收到这个异常
ORA-00902: invalid datatype
00902. 00000 - "invalid datatype"
*Cause:
*Action:
感谢任何帮助。
直接模式下的SELECT语句不能return像记录这样的复杂数据类型。
您可能想使用 table 函数来 return 您的自定义类型。这是一个非常简单的例子:
CREATE OR REPLACE PACKAGE brianl.deleteme AS
TYPE doc_rec_t IS RECORD
(
name VARCHAR2( 10 )
, age NUMBER( 3 )
);
TYPE doc_rec_tt IS TABLE OF doc_rec_t;
FUNCTION age( p_name IN VARCHAR2, p_age IN NUMBER, p_years IN INTEGER )
RETURN doc_rec_tt
PIPELINED;
END deleteme;
CREATE OR REPLACE PACKAGE BODY brianl.deleteme AS
FUNCTION age( p_name IN VARCHAR2, p_age IN NUMBER, p_years IN INTEGER )
RETURN doc_rec_tt
PIPELINED AS
l_ret doc_rec_t;
BEGIN
l_ret.name := p_name;
l_ret.age := p_age;
FOR i IN 1 .. p_years
LOOP
PIPE ROW (l_ret);
l_ret.age := l_ret.age + 1;
END LOOP;
END age;
END deleteme;
调用如下:
SELECT * FROM TABLE( brianl.deleteme.age( 'Brian', 67, 3 ) );
结果:
NAME AGE
Brian 67
Brian 68
Brian 69
我创建了一个包,其中包含一个自定义类型和一个 returns 自定义类型的函数,如下所示;
create or replace
PACKAGE INHOUSE_CUST_API
AS
TYPE doc_rec
IS
RECORD
(
doc_Title doc_issue_reference.title%Type,
doc_Number DOC_ISSUE_REFERENCE.DOC_NO%TYPE,
doc_Type DOC_ISSUE_REFERENCE.FILE_TYPE%TYPE,
doc_FileName DOC_ISSUE_REFERENCE.FILE_NAME%TYPE,
doc_Path DOC_ISSUE_REFERENCE.PATH%TYPE);
FUNCTION Get_Budget_Doc(
company IN VARCHAR2,
budget_process_id IN VARCHAR2,
budget_ptemplate_id IN VARCHAR2)
RETURN doc_rec;
END INHOUSE_CUST_API;
之后,我创建了如下函数体
create or replace
PACKAGE BODY INHOUSE_CUST_API
AS
FUNCTION Get_Budget_Doc(
company IN VARCHAR2,
budget_process_id IN VARCHAR2,
budget_ptemplate_id IN VARCHAR2)
RETURN doc_rec
IS
enhDocItem ENHANCED_DOC_REFERENCE_OBJECT%ROWTYPE;
docIssueRef DOC_ISSUE_REFERENCE%ROWTYPE;
docKeyValue VARCHAR2(150);
docIssueRef_rec doc_rec;
BEGIN
docKeyValue := company||'^'||budget_process_id||'^'||budget_ptemplate_id||'^';
--dbms_output.put_line(docKeyValue);
SELECT *
INTO enhDocItem
FROM ENHANCED_DOC_REFERENCE_OBJECT
WHERE KEY_VALUE= docKeyValue;
SELECT *
INTO docIssueRef
FROM DOC_ISSUE_REFERENCE
WHERE DOC_NO = enhDocItem.DOC_NO;
docIssueRef_rec.doc_Title :=docIssueRef.Title;
docIssueRef_rec.doc_Number:=docIssueRef.DOC_NO;
docIssueRef_rec.doc_Type :=docIssueRef.FILE_TYPE;
docIssueRef_rec.doc_Path :=docIssueRef.PATH;
RETURN docIssueRef_rec;
END Get_Budget_Doc;
END INHOUSE_CUST_API;
当我尝试像这样调用函数时 select INHOUSE_CUST_API.Get_Budget_Doc('param1','param2','param3') 来自 dual;
我收到这个异常
ORA-00902: invalid datatype 00902. 00000 - "invalid datatype" *Cause:
*Action:
感谢任何帮助。
直接模式下的SELECT语句不能return像记录这样的复杂数据类型。
您可能想使用 table 函数来 return 您的自定义类型。这是一个非常简单的例子:
CREATE OR REPLACE PACKAGE brianl.deleteme AS
TYPE doc_rec_t IS RECORD
(
name VARCHAR2( 10 )
, age NUMBER( 3 )
);
TYPE doc_rec_tt IS TABLE OF doc_rec_t;
FUNCTION age( p_name IN VARCHAR2, p_age IN NUMBER, p_years IN INTEGER )
RETURN doc_rec_tt
PIPELINED;
END deleteme;
CREATE OR REPLACE PACKAGE BODY brianl.deleteme AS
FUNCTION age( p_name IN VARCHAR2, p_age IN NUMBER, p_years IN INTEGER )
RETURN doc_rec_tt
PIPELINED AS
l_ret doc_rec_t;
BEGIN
l_ret.name := p_name;
l_ret.age := p_age;
FOR i IN 1 .. p_years
LOOP
PIPE ROW (l_ret);
l_ret.age := l_ret.age + 1;
END LOOP;
END age;
END deleteme;
调用如下:
SELECT * FROM TABLE( brianl.deleteme.age( 'Brian', 67, 3 ) );
结果:
NAME AGE
Brian 67
Brian 68
Brian 69