oracle – 如何在两个PL / SQL函数的结果之间创建连接?

我有两个函数,它们都返回一个TYPE,即:

CREATE OR REPLACE FUNCTION myUser.f_myFunction
(
    myId IN RAW := NULL
) RETURN myUser.myType
AS
    ResultTable myUser.myType;
BEGIN
    ...
    -- fill ResultTable
    ...

    RETURN ResultTable;
END;

现在我想在SELECT语句中加入它们:

SELECT *
FROM myUser.f_myFunction1() f1
JOIN myUser.f_myFunction2() f2 ON f1.xy = f2.yz;

但是如果我在SELECT语句中包含一个函数,我会收到一个错误:

SELECT * FROM myUser.f_myFunction();
                                 *
ERROR in Line 1:
ORA-00933: SQL command not properly ended
    ORA-04044: procedure, function, package, or type is not allowed here

.

编辑:将函数调用嵌套在TABLE()子句中会出现以下错误:

SELECT * FROM TABLE(myUser.f_myFunction())
              *
ERROR at line 1:
ORA-22905: cannot access rows from a non-nested table item

然后我试着施展它,但是:

SELECT * FROM TABLE(CAST(myUser.f_myFunction() AS myUser.myType))
                             *
ERROR at line 1:
ORA-22907: invalid CAST to a type that is not a nested table or VARRAY

和:

SELECT * FROM TABLE(CAST(myUser.f_myFunction() AS myUser.myTypeTable))
                             *
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected - got myUser.myType

.

编辑2:这是类型的定义(对不起,应该包括在前面):

CREATE TYPE myUser.myType AS OBJECT (
    ....
);

CREATE TYPE myUser.myTypeTable IS TABLE OF myUser.myType;

.

编辑3:让它像这样工作:

CREATE OR REPLACE FUNCTION myUser.f_myFunction
(
    myId IN RAW := NULL
) RETURN myUser.myTypeTable
AS
    ResultTable myUser.myTypeTable;
BEGIN

    SELECT myUser.myType(x.Column1, x.Column2, ...)
        BULK COLLECT INTO ResultTable
        FROM myUser.myTable x
        WHERE ...

    RETURN ResultTable;
END;

最佳答案 至少有三种方法可以做到这一点:1)CCreate嵌套表2)多次调用函数3)创建一个函数来访问每个属性.

示例对象

create or replace type myType as object
(
    wx number,
    xy number
);


CREATE OR REPLACE FUNCTION f_myFunction
(
    myId IN RAW := NULL
) RETURN myType
AS
    ResultTable myType := myType(1, 2);
BEGIN
    RETURN ResultTable;
END;
/

方法1:创建嵌套表

正如Luke Woodward指出的那样,功能TABLE和CAST需要一个嵌套的类型表.即使您只打算使用单个元素.

create or replace type myType_nt is table of myType;

CREATE OR REPLACE FUNCTION f_myFunction_nt
(
    myId IN RAW := NULL
) RETURN myType_nt
AS
    ResultTable myType_nt := myType_nt(myType(1, 2));
BEGIN
    RETURN ResultTable;
END;
/

select wx, xy from table(f_myFunction_nt());

WX  XY
--  --
1   2

方法2:对每个属性重复函数调用

如果为每个属性调用一次函数,则不需要额外的对象.这是重复的并且可能是昂贵的.将函数设置为确定性可能会阻止函数实际被多次调用.

select wx, xy from
(
    select f_myFunction().wx wx, f_myFunction().xy xy from dual
);

WX  XY
--  --
1   2

似乎应该有一个更简单的方法来做到这一点. Oracle确实支持调用该函数一次并返回具有这两个属性的类型.但是没有办法有意义地使用那种类型. SQL无法轻松访问这些属性.

SQL> select * from (select f_myFunction() from dual);

F_MYFUNCTION()(WX, XY)
-----------------------------------------------------
MYTYPE(1, 2)

简单地使用每个属性名称的直观方式不起作用.

SQL> select wx, xy from (select f_myFunction() from dual);
select wx, xy from (select f_myFunction() from dual)
           *
ERROR at line 1:
ORA-00904: "XY": invalid identifier

方法3:为每个属性创建一个函数

您可以使用函数访问属性.这需要添加新对象,但它保持您的主要功能相同.

create or replace function get_wx(p_myType myType) return number is
begin
    return p_myType.wx;
end;
/

create or replace function get_xy(p_myType myType) return number is
begin
    return p_myType.xy;
end;
/

select get_wx(asdf) wx, get_xy(asdf) xy
from (select f_myFunction() asdf from dual);

WX  XY
--  --
1   2
点赞