You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle PL/SQL:解决非嵌套表报错并封装查询输出CLOB结果

问题解决与实现方案

报错原因

报错cannot access rows from a non-nested table item是因为你定义的type_aa是关联数组(INDEX BY pls_integer),这种类型仅支持PL/SQL环境,无法在SQL语句中通过TABLE()操作符展开查询。


问题1:能否在存储过程/函数中调用get_cash_flow.func_aa?

可以调用,但需要先调整类型定义,让返回的集合能被SQL引擎识别(将关联数组改为嵌套表)。


问题2:封装JSON数组生成逻辑为存储过程/函数

步骤1:修改包定义与包体(调整集合类型)

将原包中的关联数组改为嵌套表(移除INDEX BY pls_integer),并调整包体中集合的赋值方式:

修改后的包定义

CREATE OR REPLACE PACKAGE get_cash_flow 
IS
  TYPE type_rec IS RECORD (
    asofdate VARCHAR2(30),
    cfValue VARCHAR2(30)
  );
  -- 改为嵌套表类型,支持SQL访问
  TYPE type_aa IS TABLE OF type_rec;
  FUNCTION func_aa RETURN type_aa;
END;
/

修改后的包体

CREATE OR REPLACE PACKAGE BODY get_cash_flow
IS
  FUNCTION func_aa RETURN type_aa
  IS
    l_aa_var1 get_cash_flow.type_aa;
  BEGIN
    FOR loop_aa IN (
      SELECT 
        asofdate, 
        -- 简化计算表达式(原表达式存在重复减项,可按需调整)
        cash_inflow + TRANSFERS + ASSET_INFLOW + INTEREST_INCOME_LONG + DIVIDEND_INCOME 
        - 2*CASH_OUTFLOW - 2*ASSET_OUTFLOW 
        + INTEREST_INCOME_SHORT + MANAGEMENT_FEE + OTHER_FEES + EXPENSES AS cfValue 
      FROM eod_value_account_mtbl 
      ORDER BY asofdate
      FETCH FIRST 500 rows only
    ) LOOP
      l_aa_var1.EXTEND; -- 扩展嵌套表容量
      l_aa_var1(l_aa_var1.LAST).asofdate := loop_aa.asofdate;
      l_aa_var1(l_aa_var1.LAST).cfValue := loop_aa.cfValue;
    END LOOP;
    RETURN l_aa_var1;
  END func_aa;
END get_cash_flow;
/

步骤2:封装生成JSON数组的函数

创建返回CLOB类型的函数,直接返回JSON数组:

CREATE OR REPLACE FUNCTION get_cash_flow_json RETURN CLOB
IS
  vcResult CLOB;
  l_aa_var1 get_cash_flow.type_aa;
BEGIN
  -- 调用原函数获取数据集合
  l_aa_var1 := get_cash_flow.func_aa;
  
  -- 转换为JSON数组CLOB
  SELECT JSON_ARRAYAGG(
    JSON_OBJECT(
      KEY 'cfDate' VALUE asofdate,
      KEY 'cfValue' VALUE cfValue
    ) FORMAT JSON
    RETURNING CLOB
  ) INTO vcResult
  FROM TABLE(l_aa_var1);
  
  RETURN vcResult;
END;
/

步骤3:测试函数

执行以下代码验证结果:

DECLARE
  v_json_result CLOB;
BEGIN
  v_json_result := get_cash_flow_json;
  DBMS_OUTPUT.PUT_LINE(v_json_result);
END;
/

可选:封装为存储过程(带输出参数)

如果需要用存储过程实现,可创建带OUT参数的版本:

CREATE OR REPLACE PROCEDURE get_cash_flow_json_proc(p_json_result OUT CLOB)
IS
  l_aa_var1 get_cash_flow.type_aa;
BEGIN
  l_aa_var1 := get_cash_flow.func_aa;
  
  SELECT JSON_ARRAYAGG(
    JSON_OBJECT(
      KEY 'cfDate' VALUE asofdate,
      KEY 'cfValue' VALUE cfValue
    ) FORMAT JSON
    RETURNING CLOB
  ) INTO p_json_result
  FROM TABLE(l_aa_var1);
END;
/

测试存储过程

DECLARE
  v_json_result CLOB;
BEGIN
  get_cash_flow_json_proc(v_json_result);
  DBMS_OUTPUT.PUT_LINE(v_json_result);
END;
/

内容的提问来源于stack exchange,提问作者user19427142

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 12:06:44