Oracle Apex Set Value动作报JSON.WRITER.NOT_OPEN错误求助
问题
在SQL Workshop中运行以下代码可正常执行,但移除DBMS_OUTPUT语句后将其用于应用的Set Value动作时,出现错误:Ajax调用返回服务器错误ORA-20987: APEX - JSON.WRITER.NOT_OPEN,调试ID"354017"未提供更多有效信息,且此代码几天前还能正常运行。
代码如下:
declare l_request_url varchar2(32767); l_content_type varchar2(32767); l_content_length varchar2(32767); l_response varchar2(10000); l_body_clob clob; l_name varchar2(200); download_failed_exception exception; j apex_json.t_values; n_customer_id number; begin l_request_url := 'https://mysterysite.com/api/v3/customer'; APEX_JSON.initialize_clob_output; APEX_JSON.open_object; APEX_JSON.write('company', :P5_COMPANY); APEX_JSON.write('bill_addr1', :P5_BILL_ADDR1); APEX_JSON.write('bill_addr2', :P5_BILL_ADDR2); APEX_JSON.write('bill_city', :P5_BILL_CITY); APEX_JSON.write('bill_postcode', :P5_BILL_POSTCODE); APEX_JSON.write('superuser_email', :P5__YOUR_EMAIL); APEX_JSON.close_object; l_body_clob :=APEX_JSON.get_clob_output; APEX_JSON.free_output; apex_web_service.g_request_headers.delete(); apex_web_service.g_request_headers(1).name := 'Content-Type'; apex_web_service.g_request_headers(1).value := 'application/json'; l_response := apex_web_service.make_rest_request( p_url => l_request_url , p_http_method => 'POST' , p_username => 'junk username' , p_password => 'junkpassword' , p_body => l_body_clob ); if apex_web_service.g_status_code != 201 then DBMS_OUTPUT.PUT_LINE('ERROR'); else apex_json.Parse (j, l_response); n_customer_id := apex_json.get_varchar2 (p_values => j, p_path => 'response.id'); DBMS_OUTPUT.PUT_LINE(n_customer_id); end if; end;
环境信息
- 产品版本:22.2.1
- Schema兼容性:2022.10.07
- 补丁版本:1
- 最后补丁时间:2022年12月26日 下午05:32:28
- 最后DDL时间:2022年12月26日 下午04:37:11
- 宿主Schema:ORDS_PLSQL_GATEWAY
- 应用所有者:APEX_220200
解决方案
- 问题根源:Set Value动作要求代码必须返回明确的值,移除
DBMS_OUTPUT后,你的代码没有任何返回语句,APEX会自动尝试解析JSON输出,但代码里手动管理了APEX_JSON的输出流,两者冲突导致报错。另外,就算接口调用成功,解析出的n_customer_id也没传递给Set Value动作,相当于代码执行完没给APEX想要的结果。 - 修复步骤:
- 添加返回逻辑:如果要把
n_customer_id赋值给页面项,就在else分支里加:P5_CUSTOMER_ID := n_customer_id;(替换成你实际要赋值的页面项);错误分支也要处理,比如设置:P5_CUSTOMER_ID := -1;或者抛出明确异常,别让代码跑完无结果。 - 简化JSON生成:用
APEX_JSON.generate直接生成请求体,避免手动管理输出流的麻烦,代码更简洁也不容易出问题,替换原有JSON生成代码:l_body_clob := APEX_JSON.generate( p_values => apex_json.t_object( 'company' => :P5_COMPANY, 'bill_addr1' => :P5_BILL_ADDR1, 'bill_addr2' => :P5_BILL_ADDR2, 'bill_city' => :P5_BILL_CITY, 'bill_postcode' => :P5_BILL_POSTCODE, 'superuser_email' => :P5__YOUR_EMAIL ) ); - 检查Set Value配置:确认动作选择了"返回单个值",并指定了正确的目标页面项,确保APEX明确知道要接收什么结果。
- 添加返回逻辑:如果要把
内容的提问来源于stack exchange,提问作者Android
相关产品推荐
相关产品推荐

