Oracle Can';t使用动态SQL从返回表的函数中检索数据

Oracle Can';t使用动态SQL从返回表的函数中检索数据,oracle,stored-procedures,dynamic,Oracle,Stored Procedures,Dynamic,我的类型: TYPE T_rowBalanceListForClient IS RECORD ( RowCode Asset.RowCode%TYPE, RowName Asset.RowName%TYPE ); TYPE T_tableBalanceListForClient IS TABLE OF T_rowBalanceListForClient; 我的职能: FUNCTION F_BalanceListForClient ( p_ClientId Clien

我的类型:

TYPE T_rowBalanceListForClient IS RECORD
(
    RowCode Asset.RowCode%TYPE,
    RowName Asset.RowName%TYPE
);  
TYPE T_tableBalanceListForClient IS TABLE OF T_rowBalanceListForClient;
我的职能:

FUNCTION F_BalanceListForClient
(
    p_ClientId Client.ClientId%TYPE
)
RETURN T_tableBalanceListForClient PIPELINED
AS
    CURSOR CUR_TABLE IS
        SELECT
                RowCode,
                RowName
            FROM Asset;
BEGIN

    FOR CUR_REC IN CUR_TABLE LOOP
        PIPE ROW(CUR_REC);
    END LOOP;

END;
我的存储过程的一部分:

    sql_statement := ' SELECT * FROM TABLE(:1)';
    OPEN c_Result FOR sql_statement USING F_BalanceListForClient(11);
构建包时,我重新发送Oracle错误:

PLS-00457:表达式必须是SQL类型

在常见的存储过程中,这样的调用是构建的,并且运行良好(不是动态的):

谢谢你的帮助。
谢谢。

您是否尝试过使用
表格(F\u BalanceListForClient(:1))
?是的,这是我第一次尝试。错误是“不正确的标识符”或类似的情况。我搜索了一整天,找到了我在问题中描述的解决方案,但它也返回了错误。是
F\u BalanceListForClient
类型
T\u tableBalanceListForClient
?是的,Jafar,你可以在函数体中看到它。感谢Gaurav提供的解决方案,但我决定使用“视图”而不是函数。它看起来更整洁,工作正常。不幸的是,我无法提高您的评分-我缺少我的评分,但如果我的评分超过15分,我会这样做。@xborus:这与评分无关,请尝试了解如何实现这一点,这对我们来说更重要。仅供参考,提高评分不会降低您的评分,也不会降低您接受答案的程度。事实上,如果您接受答案,您将获得2个声誉。但没有问题,我的目的是让您意识到这一点,分享并享受:)
PROCEDURE GET_BALANCE_STANDARD_LIST
(
    c_Result OUT SYS_REFCURSOR,
    p_ClientId Client.ClientId%TYPE DEFAULT NULL
)
AS
BEGIN
    OPEN c_Result FOR
        SELECT RowName FROM TABLE(F_BalanceListForClient(p_ClientId));
END;
CREATE OR REPLACE TYPE T_rowBalanceListForClient IS OBJECT 
(
    RowCode NUMBER,
    RowName VARCHAR2(200)
);  


CREATE OR REPLACE TYPE T_tableBalanceListForClient AS TABLE OF T_rowBalanceListForClient;
/


CREATE OR REPLACE FUNCTION F_BalanceListForClient
(
    p_ClientId NUMBER        
)
RETURN T_tableBalanceListForClient PIPELINED
AS
CURSOR CUR_TABLE IS
        SELECT
                RowCode,
                RowName
            FROM Assets
          ;    --put a filter of the p_clientId


BEGIN

    FOR CUR_REC IN CUR_TABLE
    LOOP

       pipe row (T_rowBalanceListForClient (CUR_REC.RowCode, CUR_REC.RowName));

    END LOOP;

RETURN;

END;
/


CREATE OR REPLACE PROCEDURE GET_BALANCE_STANDARD_LIST
(
    c_Result OUT SYS_REFCURSOR,
    p_ClientId NUMBER DEFAULT NULL
)
AS
sql_statement varchar2(200);

BEGIN

 sql_statement := ' SELECT * FROM TABLE(F_BalanceListForClient(:1))';
    OPEN c_Result FOR sql_statement USING p_ClientId;

END;
/

BEGIN

GET_BALANCE_STANDARD_LIST(:cur ,11);

END;
/