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

Oracle 12c基于表数据生成指定结构JSON的技术求助

Oracle 12c生成指定格式JSON的解决方案

环境与基础数据

使用Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit,已创建temp_Table表并插入数据:

CREATE TABLE temp_Table 
(
    "OVRPK_CNTNR_ID" CHAR(20) NOT NULL ENABLE, 
    "ITEM_DISTB_Q" NUMBER(3) NOT NULL ENABLE,
    "SSP_Q" NUMBER(6,0) NOT NULL ENABLE, 
    "BRKPK_CNTNR_ID" CHAR(20)
);

INSERT INTO temp_Table (OVRPK_CNTNR_ID, ITEM_DISTB_Q, SSP_Q, BRKPK_CNTNR_ID ) VALUES('92000000356873110552', 6,8,'93058901021076000085');
INSERT INTO temp_Table (OVRPK_CNTNR_ID,ITEM_DISTB_Q,SSP_Q, BRKPK_CNTNR_ID ) VALUES('92000000356873110552',8, 10,'93058901021117700080');
INSERT INTO temp_Table (OVRPK_CNTNR_ID,ITEM_DISTB_Q,SSP_Q, BRKPK_CNTNR_ID ) VALUES('92000000356873110552', 10,2,'93058901022276900083');
INSERT INTO temp_Table (OVRPK_CNTNR_ID,ITEM_DISTB_Q,SSP_Q, BRKPK_CNTNR_ID ) VALUES('92000000334160826089', 3,4,'000000000083465239'); 
INSERT INTO temp_Table (OVRPK_CNTNR_ID,ITEM_DISTB_Q,SSP_Q, BRKPK_CNTNR_ID ) VALUES('92000000334160826089', 3,4,'000000000083438160');

原实现的问题

原编写的触发器和createJson函数存在语法错误,且未正确匹配期望的JSON结构:

-- 原触发器
AFTER INSERT OR DELETE OR UPDATE OF 
OVRPK_CNTNR_ID, ITEM_DISTB_Q, SSP_Q, BRKPK_CNTNR_ID
ON temp_Table 
FOR EACH ROW

DECLARE 
    json_message    CLOB := '';

BEGIN
    /*
     * pick OVRPK_CNTNR_ID from triggers row and send it to function createJson() return json object, example : 92000000356873110552
     */

    json_message = CALL FUNCTION createJson(:NEW.OVRPK_CNTNR_ID);

END;

-- 原createJson函数
CREATE OR REPLACE FUNCTION createJson(ovrpk_container_id IN char)

BEGIN
SELECT json_query(
                    json_objectagg(OVRPK_CNTNR_ID value 
                                    json_array(
                                                json_object("break_pack_container_id" VALUE BRKPK_CNTNR_ID,
                                                            "ssp_quantity" VALUE SSP_Q,
                                                            "item_distribution_quantity" VALUE ITEM_DISTB_Q)))),
                                                            
 '$' returning VARCHAR2(4000) pretty )
    AS "Result JSON" 
  FROM temp_Table
END;

期望的JSON输出格式

{
  "Over_pack_container_id":"92000000356873110552",
  "type": "OVER_PACK",
  "sub_containers": [
    {
      "break_pack_container_id": "93058901021076000085",
      "ssp_quantity": 8,
      "item_distribution_quantity": 6
    },    
    {
      "break_pack_container_id": "93058901021117700080",
      "ssp_quantity": 10,
      "item_distribution_quantity": 8
    },
    {
      "break_pack_container_id": "93058901022276900083",
      "ssp_quantity": 2,
      "item_distribution_quantity": 10
    }
  ]
}

修正后的可行实现

Oracle 12.1.0.2支持JSON_OBJECT、JSON_ARRAYAGG等JSON构造函数,以下是修正后的代码:

1. 修正后的createJson函数

CREATE OR REPLACE FUNCTION createJson(p_ovrpk_container_id IN CHAR)
RETURN CLOB
IS
    v_json CLOB;
BEGIN
    SELECT JSON_OBJECT(
               'Over_pack_container_id' VALUE t."OVRPK_CNTNR_ID",
               'type' VALUE 'OVER_PACK',
               'sub_containers' VALUE JSON_ARRAYAGG(
                   JSON_OBJECT(
                       'break_pack_container_id' VALUE t."BRKPK_CNTNR_ID",
                       'ssp_quantity' VALUE t."SSP_Q",
                       'item_distribution_quantity' VALUE t."ITEM_DISTB_Q"
                   )
               ) FORMAT JSON
           ) INTO v_json
    FROM temp_Table t
    WHERE t."OVRPK_CNTNR_ID" = p_ovrpk_container_id
    GROUP BY t."OVRPK_CNTNR_ID";
    
    RETURN v_json;
END;
/

说明:

  • 用JSON_OBJECT构造外层对象,严格匹配预期的键名
  • 通过JSON_ARRAYAGG聚合同一容器ID下的子数据,生成数组结构
  • 指定返回类型为CLOB,避免VARCHAR2的长度限制
  • 增加GROUP BY确保按容器ID聚合数据

2. 修正后的触发器

CREATE OR REPLACE TRIGGER temp_table_after_change
AFTER INSERT OR DELETE OR UPDATE OF OVRPK_CNTNR_ID, ITEM_DISTB_Q, SSP_Q, BRKPK_CNTNR_ID
ON temp_Table 
FOR EACH ROW
DECLARE 
    json_message CLOB := '';
BEGIN
    -- 插入/更新时取新值,删除时取旧值
    IF INSERTING OR UPDATING THEN
        json_message := createJson(:NEW."OVRPK_CNTNR_ID");
    ELSE
        json_message := createJson(:OLD."OVRPK_CNTNR_ID");
    END IF;
    
    -- 此处可替换为实际业务逻辑,比如输出日志、调用外部接口等
    DBMS_OUTPUT.PUT_LINE(json_message);
END;
/

说明:

  • 补全触发器名称,符合Oracle语法规范
  • 修正函数调用方式,直接赋值而非错误的CALL FUNCTION语法
  • 处理删除场景,使用:OLD获取被删除的容器ID
  • 添加DBMS_OUTPUT示例,方便验证结果

验证结果

触发触发器操作后,将生成与预期格式完全一致的JSON内容。例如,对92000000356873110552相关数据进行增删改时,输出的JSON结构完全匹配需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 22:00:54