如何在Oracle 11g的SQL中在一个函数中获取另一个函数的结果?
解决Oracle 11g中函数调用返回游标函数的问题
你的代码无法运行的核心原因是:sys_refcursor是PL/SQL专属的游标类型,不能直接在SQL语句的FROM子句中当作表来查询,所以select * from getSomt()这种写法是不合法的。下面提供两种可行的解决方案:
方案一:将源函数改为返回SQL可识别的集合类型
如果可以修改getSomt函数,建议把它改成返回嵌套表类型,这样就能在SQL中通过TABLE()函数直接引用结果。
- 先定义全局的对象类型和嵌套表类型:
CREATE TYPE field_rec AS OBJECT (field VARCHAR2(1)); CREATE TYPE field_tab AS TABLE OF field_rec;
- 修改
getSomt函数返回嵌套表:
CREATE FUNCTION getSomt RETURN field_tab IS v_tab field_tab := field_tab(); BEGIN v_tab.extend(); v_tab(1) := field_rec('Y'); RETURN v_tab; END getSomt;
- 编写
doWork函数,直接在SQL中调用getSomt:
CREATE FUNCTION doWork RETURN sys_refcursor IS vResult sys_refcursor; BEGIN OPEN vResult FOR SELECT * FROM TABLE(getSomt()) WHERE field = 'N'; RETURN vResult; END doWork;
方案二:保留原函数,用BULK COLLECT处理游标
如果不想修改getSomt函数,可以在doWork中先获取getSomt的游标结果,用BULK COLLECT批量存入集合,再基于集合构造结果游标。
CREATE FUNCTION doWork RETURN sys_refcursor IS v_src_cursor sys_refcursor; -- 定义与源游标匹配的集合类型 TYPE field_tab IS TABLE OF VARCHAR2(1); v_tab field_tab := field_tab(); vResult sys_refcursor; BEGIN -- 获取getSomt返回的游标 v_src_cursor := getSomt(); -- 批量收集游标数据到集合 FETCH v_src_cursor BULK COLLECT INTO v_tab; CLOSE v_src_cursor; -- 基于集合打开结果游标,筛选符合条件的数据 OPEN vResult FOR SELECT column_value AS field FROM TABLE(v_tab) WHERE column_value = 'N'; RETURN vResult; END doWork;
如果需要逐行处理(而非批量),也可以用循环遍历游标,筛选后存入集合,再返回游标:
CREATE FUNCTION doWork RETURN sys_refcursor IS v_src_cursor sys_refcursor; v_field VARCHAR2(1); TYPE field_tab IS TABLE OF VARCHAR2(1); v_tab field_tab := field_tab(); vResult sys_refcursor; BEGIN v_src_cursor := getSomt(); LOOP FETCH v_src_cursor INTO v_field; EXIT WHEN v_src_cursor%NOTFOUND; -- 筛选符合条件的数据 IF v_field = 'N' THEN v_tab.extend(); v_tab(v_tab.count) := v_field; END IF; END LOOP; CLOSE v_src_cursor; OPEN vResult FOR SELECT column_value AS field FROM TABLE(v_tab); RETURN vResult; END doWork;
内容的提问来源于stack exchange,提问作者deni5n
相关产品推荐
相关产品推荐

