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

如何解决传递大量JSON时的'unimplemented or unreasonable conversion requested'错误

解决大量JSON记录传递至Oracle服务器的问题

针对你遇到的大量JSON记录传递报错问题,以下是几种可行的解决方法:

方案1:分段批量传递记录

将大量记录拆分成多个小批次,客户端分批调用服务器函数,避免单次传递的字符串/CLOB长度超出限制。

客户端代码示例:

DECLARE
    SelectionVar VARCHAR2(32000);
    invoiceExist VARCHAR2(10) := 'N';
    total_records NUMBER := 10000; -- 总记录数
    batch_size NUMBER := 1000; -- 每批次记录数
    start_idx NUMBER;
    end_idx NUMBER;
BEGIN
    FOR batch IN 1 .. CEIL(total_records / batch_size) LOOP
        start_idx := (batch - 1) * batch_size + 1;
        end_idx := LEAST(batch * batch_size, total_records);
        -- 生成当前批次的JSON字符串
        stringify(rec(start_idx..end_idx), "IS_TRANSACTION=${IsTransaction}^COMPANY_ID=${CompanyId}^PR_TRANSACTION_SEQ=${PrTransactionSeq}^SPRICE=${SPrice}^SQUANTITY=${SQuantity}^", JSON) into SelectionVar;
        -- 调用服务器函数,只要某批次存在发票就标记为存在
        IF Get_Records(SelectionVar) = 'Y' THEN
            invoiceExist := 'Y';
        END IF;
    END LOOP;
END;
/

方案2:使用Oracle集合类型替代JSON传递

放弃JSON序列化,直接使用Oracle自定义的记录集合类型传递数据,避免JSON转换的开销和长度限制,同时提升处理效率。

步骤1:服务器端定义自定义类型

-- 定义单条记录的类型
CREATE OR REPLACE TYPE RECORD_TYPE AS OBJECT (
    IS_TRANSACTION VARCHAR2(10),
    COMPANY_ID NUMBER,
    PR_TRANSACTION_SEQ NUMBER,
    SPRICE NUMBER,
    SQUANTITY NUMBER
);
/
-- 定义记录数组类型
CREATE OR REPLACE TYPE RECORD_ARRAY AS TABLE OF RECORD_TYPE;
/

步骤2:修改服务器端Get_Records函数

FUNCTION Get_Records(
   records_  IN RECORD_ARRAY )  RETURN VARCHAR2
IS 
   invoiceExist VARCHAR2(10) := 'N';
BEGIN
   -- 直接遍历集合处理每条记录
   FOR i IN records_.FIRST .. records_.LAST LOOP
       -- 执行你的修改逻辑,例如更新表或检查发票存在性
       IF EXISTS (SELECT 1 FROM invoices WHERE COMPANY_ID = records_(i).COMPANY_ID) THEN
           invoiceExist := 'Y';
       END IF;
   END LOOP;
   RETURN invoiceExist;
END;
/

步骤3:客户端调用代码

DECLARE
    rec_array RECORD_ARRAY := RECORD_ARRAY();
    invoiceExist VARCHAR2(10);
BEGIN
    -- 批量添加记录到集合
    rec_array.EXTEND(1000); -- 扩展集合容量
    rec_array(1) := RECORD_TYPE('Y', 123, 456, 100.0, 5);
    -- 继续添加更多记录...
    rec_array(1000) := RECORD_TYPE('N', 789, 1011, 200.0, 2);
    
    -- 调用服务器函数
    invoiceExist := Get_Records(rec_array);
END;
/

方案3:优化CLOB类型的JSON传递

如果必须使用JSON,确保客户端直接生成并传递CLOB类型,而非先转成VARCHAR2再转CLOB,同时优化服务器端的JSON解析逻辑。

服务器端修改后的函数

FUNCTION Get_Records(
   selection_clob_  IN CLOB )  RETURN VARCHAR2
IS 
   records_               json_array := json_array.parse(selection_clob_);
   invoiceExist VARCHAR2(10) := 'N';
   current_obj            json_object;
BEGIN
    -- 遍历JSON数组处理每条记录
    FOR i IN 0 .. records_.get_size() - 1 LOOP
        current_obj := records_.get(i).to_json_object();
        -- 执行你的修改或检查逻辑
        IF current_obj.get_number('COMPANY_ID') IS NOT NULL THEN
            -- 示例逻辑:检查发票是否存在
            IF EXISTS (SELECT 1 FROM invoices WHERE COMPANY_ID = current_obj.get_number('COMPANY_ID')) THEN
                invoiceExist := 'Y';
            END IF;
        END IF;
    END LOOP;
    RETURN invoiceExist;
END;
/

客户端生成CLOB的代码示例

DECLARE
    SelectionVar CLOB;
    invoiceExist VARCHAR2(10);
BEGIN
    -- 直接从数据源生成CLOB类型的JSON数组,避免中间VARCHAR2转换
    SELECT json_arrayagg(
        json_object(
            'IS_TRANSACTION' VALUE IsTransaction,
            'COMPANY_ID' VALUE CompanyId,
            'PR_TRANSACTION_SEQ' VALUE PrTransactionSeq,
            'SPRICE' VALUE SPrice,
            'SQUANTITY' VALUE SQuantity
        )
    ) INTO SelectionVar FROM your_source_table; -- 替换为你的记录来源
    
    invoiceExist := Get_Records(SelectionVar);
END;
/

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:15:01