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;
/