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

存储过程无法返回长字符串响应的解决方案咨询

问题:存储过程返回长JSON为空,短JSON正常

存储过程PR_GETECOUNT在返回较长JSON字符串时响应为空,短JSON则正常返回,推测是字符类型长度限制导致。

原存储过程代码

create or replace PROCEDURE PR_GETECOUNT  
( P_YEAR IN NUMBER
,P_RECORDSET OUT  NVARCHAR2
) AS 
l_r_count varchar2(400);
l_v_count varchar2(400);
l_e_count varchar2(400);
l_p_count varchar2(400);
l_s_count varchar2(400);
l_n_count varchar2(400);
l_e_count_upadted  NVARCHAR2(4000);
BEGIN

l_r_count:=FN_GETECOUNT( 'R',P_YEAR);
l_v_count:=FN_GETECOUNT( 'V',P_YEAR);
l_e_count:=FN_GETECOUNT( 'E',P_YEAR);
l_p_count:=FN_GETECOUNT( 'P',P_YEAR);
l_s_count:=FN_GETECOUNT( 'S',P_YEAR);
l_n_count:=FN_GETECOUNT( 'N',P_YEAR);

--the values returned by FN_GETECOUNT are as below
l_r_count:='{"R":[375,127,136,650,130,169,009,015,094,027]}';
l_v_count:='{"V":[375,127,136,650,130,169,009,015,094,027]}';
l_e_count:='{"E":[375,127,136,650,130,169,009,015,094,027]}';
l_p_count:='{"P":[375,127,136,650,130,169,009,015,094,027]}';
l_s_count:='{"S":[375,127,136,650,130,169,009,015,094,027]}';
l_n_count:='{"N":[375,127,136,650,130,169,009,015,094,027]}';

--preparing response
l_e_count_upadted:='['||l_r_count||','||l_v_count||','||l_e_count||','||l_p_count||','||l_s_count||','||l_n_count||']' ;

  select l_e_count_upadted INTO P_RECORDSET FROM dual;
  

END PR_GETECOUNT;

现象

  • 预期返回的长JSON:
[{"R":[375,127,136,650,130,169,009,015,094,027]},{"V":[375,127,136,650,130,169,009,015,094,027]},{"E":[375,127,136,650,130,169,009,015,094,027]},{"P":[375,127,136,650,130,169,009,015,094,027]},{"S":[375,127,136,650,130,169,009,015,094,027]},{"N":[375,127,136,650,130,169,009,015,094,027]}]
  • 实际返回为空;但短JSON(如下)能正常返回:
[{"R":[0,0,0,0,1,0,0,0,0,0]},{"V":[0,0,0,0,0,0,0,0,0,1]},{"E":[0,0,0,0,0,0,0,0,0,0]},{"P":[0,0,0,0,0,0,0,0,0,0]},{"S":[4,7,2,4,12,2,3,3,9,0]},{"N":[17,3,23,4,44,55,5,2,1,0]}]

问题分析

原代码中l_e_count_upadted定义为NVARCHAR2(4000),这是Oracle中NVARCHAR2的最大字符长度限制。当拼接后的长JSON字符串长度超过4000字符时,会触发静默截断或赋值失败,最终导致输出参数P_RECORDSET为空。

解决办法

方法1:改用CLOB类型存储长字符串

CLOB支持最大4GB的存储容量,完全满足长JSON的需求。修改存储过程的参数和中间变量类型:

create or replace PROCEDURE PR_GETECOUNT  
( P_YEAR IN NUMBER
,P_RECORDSET OUT  CLOB
) AS 
l_r_count CLOB;
l_v_count CLOB;
l_e_count CLOB;
l_p_count CLOB;
l_s_count CLOB;
l_n_count CLOB;
l_e_count_upadted  CLOB;
BEGIN

l_r_count:=FN_GETECOUNT( 'R',P_YEAR);
l_v_count:=FN_GETECOUNT( 'V',P_YEAR);
l_e_count:=FN_GETECOUNT( 'E',P_YEAR);
l_p_count:=FN_GETECOUNT( 'P',P_YEAR);
l_s_count:=FN_GETECOUNT( 'S',P_YEAR);
l_n_count:=FN_GETECOUNT( 'N',P_YEAR);

-- 测试用赋值(实际保留原函数调用即可)
l_r_count:='{"R":[375,127,136,650,130,169,009,015,094,027]}';
l_v_count:='{"V":[375,127,136,650,130,169,009,015,094,027]}';
l_e_count:='{"E":[375,127,136,650,130,169,009,015,094,027]}';
l_p_count:='{"P":[375,127,136,650,130,169,009,015,094,027]}';
l_s_count:='{"S":[375,127,136,650,130,169,009,015,094,027]}';
l_n_count:='{"N":[375,127,136,650,130,169,009,015,094,027]}';

-- 拼接CLOB字符串
l_e_count_upadted := '[' || l_r_count || ',' || l_v_count || ',' || l_e_count || ',' || l_p_count || ',' || l_s_count || ',' || l_n_count || ']';

P_RECORDSET := l_e_count_upadted;

END PR_GETECOUNT;

注意:如果FN_GETECOUNT返回的是VARCHAR2,可以直接赋值给CLOB变量,Oracle会自动转换。

方法2:使用Oracle原生JSON函数构建JSON

Oracle 12c及以上版本支持JSON_ARRAY、JSON_OBJECT等原生函数,能更规范地构建JSON,同时避免手动拼接的长度问题:

create or replace PROCEDURE PR_GETECOUNT  
( P_YEAR IN NUMBER
,P_RECORDSET OUT  CLOB
) AS 
l_r_json CLOB;
l_v_json CLOB;
l_e_json CLOB;
l_p_json CLOB;
l_s_json CLOB;
l_n_json CLOB;
BEGIN

-- 假设FN_GETECOUNT返回的是数组字符串(如'[375,127,...]'),直接用JSON_OBJECT构建
l_r_json := JSON_OBJECT('R' VALUE FN_GETECOUNT('R', P_YEAR) FORMAT JSON);
l_v_json := JSON_OBJECT('V' VALUE FN_GETECOUNT('V', P_YEAR) FORMAT JSON);
l_e_json := JSON_OBJECT('E' VALUE FN_GETECOUNT('E', P_YEAR) FORMAT JSON);
l_p_json := JSON_OBJECT('P' VALUE FN_GETECOUNT('P', P_YEAR) FORMAT JSON);
l_s_json := JSON_OBJECT('S' VALUE FN_GETECOUNT('S', P_YEAR) FORMAT JSON);
l_n_json := JSON_OBJECT('N' VALUE FN_GETECOUNT('N', P_YEAR) FORMAT JSON);

-- 用JSON_ARRAY组合成最终JSON数组
SELECT JSON_ARRAY(l_r_json, l_v_json, l_e_json, l_p_json, l_s_json, l_n_json FORMAT JSON)
INTO P_RECORDSET
FROM dual;

END PR_GETECOUNT;

这种方式不仅避免了长度限制,还能保证JSON格式的正确性,减少手动拼接的错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 21:54:54