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

Oracle表JSON字段提取指定元素为列的技术求助

提取Oracle CLOB列中JSON的动态元素并处理数值格式问题

我有一张Oracle表TEST_TABLE,其中importdata列(CLOB类型)存储JSON数据,需要提取JSON中的HMETHOD(别名HMETH)和HPRCSN两个元素,将其展示为独立列。

测试用表及数据

create table TEST_TABLE(id number,importdata clob);  

insert into TEST_TABLE values (100,'{"ClassId":30074,"Attributes":[{"Name":"TYPE-SPEC","Value":"SJ;3;1"},{"Name":"HREF","Value":"-1"},{"Name":"HMETHOD","Value":"96"},{"Name":"GEO_METHOD","Value":"96"},{"Name":"HPRCSN","Value":2.7676}]}');
insert into TEST_TABLE values (101,'{"ClassId":30074,"Attributes":[{"Name":"TYPE-SPEC","Value":"SJ;3;1"},{"Name":"HREF","Value":"-1"},{"Name":"HMETHOD","Value":"96"},{"Name":"HPRCSN","Value":3.04}]}');
insert into TEST_TABLE values (102,'{"ClassId":30074,"Attributes":[{"Name":"TYPE-SPEC","Value":"SJ;3;1"},{"Name":"HREF","Value":"-1"},{"Name":"HMETHOD","Value":"96"},{"Name":"GEO_METHOD","Value":"96"},{"Name":"HPRCSN","Value":77.1814}]}');
insert into TEST_TABLE values (103,'{"ClassId":30074,"Attributes":[{"Name":"TYPE-SPEC","Value":"SJ;3;1"},{"Name":"HREF","Value":"-1"},{"Name":"HMETHOD","Value":"96"},{"Name":"GEO_METHOD","Value":"-1"},{"Name":"HPRCSN","Value":3.1121}]}');
insert into TEST_TABLE values (105,'{"ClassId":32000,"Attributes":[{"Name":"ID","Value":"69804"},{"Name":"HREF","Value":"-1"},{"Name":"HPRCSN","Value":"5"}]},{"Name":"HMETHOD","Value":"96"} ');
insert into TEST_TABLE values (106,'{"ClassId":32000,"Attributes":[{"Name":"ID","Value":"73576"},{"Name":"HREF","Value":"-1"},{"Name":"HPRCSN","Value":"5"}]},{"Name":"HMETHOD","Value":"96"}]} ');
insert into TEST_TABLE values (107,'{"ClassId":32000,"Attributes":[{"Name":"ID","Value":"73589"},{"Name":"HREF","Value":"-1"},{"Name":"HPRCSN","Value":"5"}]},{"Name":"HMETHOD","Value":"96"}]} ');
insert into TEST_TABLE values (108,'{"ClassId":32000,"Attributes":[{"Name":"ID","Value":"74015"},{"Name":"HREF","Value":"-1"},{"Name":"HPRCSN","Value":"5"}]},{"Name":"HMETHOD","Value":"96"}]} ');
commit;

遇到的问题

  • 元素在JSON中的位置不固定,固定位置截取的方法完全失效
  • HPRCSN的值格式不统一:整数带双引号,小数无引号,直接转换为数值时会出现格式错误

现有SQL(仅部分有效)

select t1.id
,to_number(regexp_substr(replace(regexp_replace(importdata, '[^,[:digit:]]',''),',,',','),'[^,]+',15)) as HMETH
,to_number(regexp_substr(replace(regexp_replace(importdata, '[^,[:digit:]]',''),',,',','),'[^,]+',18)) as HPRCSN
from TEST_TABLE t1;

修正方案

方案一:使用Oracle原生JSON函数(推荐,Oracle 12c及以上版本)

Oracle 12c及以上提供了原生JSON处理函数,能精准解析JSON结构,不受元素位置影响,同时自动处理数值格式问题。

注意:测试数据中部分JSON存在语法错误(如id=105、106的JSON,Attributes数组闭合后额外出现独立对象),需先修正JSON结构再解析:

SELECT 
    t.id,
    -- 提取HMETHOD的数值
    JSON_VALUE(
        -- 修正无效JSON:将Attributes数组外的HMETHOD对象合并到数组内
        REGEXP_REPLACE(t.importdata, '(\]\}),(\{"Name":"HMETHOD".*?\})', '\1,\2]'),
        '$.Attributes[*]?(@.Name == "HMETHOD").Value' 
        RETURNING NUMBER
    ) AS HMETH,
    -- 提取HPRCSN的数值
    JSON_VALUE(
        REGEXP_REPLACE(t.importdata, '(\]\}),(\{"Name":"HMETHOD".*?\})', '\1,\2]'),
        '$.Attributes[*]?(@.Name == "HPRCSN").Value' 
        RETURNING NUMBER
    ) AS HPRCSN
FROM TEST_TABLE t;
  • JSON_VALUE配合JSON路径表达式$.Attributes[*]?(@.Name == "XXX"),能精准定位Attributes数组中Name匹配的元素,不受位置影响
  • RETURNING NUMBER会自动识别带引号的整数和不带引号的小数,统一转换为数值类型

方案二:使用正则表达式(兼容Oracle 12c以下版本)

如果无法使用原生JSON函数,可编写鲁棒性更强的正则表达式,不依赖元素位置,同时处理带引号/不带引号的数值:

SELECT 
    t.id,
    -- 提取HMETHOD的Value,匹配带/不带引号的数值
    TO_NUMBER(REGEXP_SUBSTR(t.importdata, '"HMETHOD":"?([0-9\.]+)"?', 1, 1, NULL, 1)) AS HMETH,
    -- 提取HPRCSN的Value,匹配带/不带引号的数值
    TO_NUMBER(REGEXP_SUBSTR(t.importdata, '"HPRCSN":"?([0-9\.]+)"?', 1, 1, NULL, 1)) AS HPRCSN
FROM TEST_TABLE t;
  • 正则表达式"HMETHOD":"?([0-9\.]+)"?匹配"HMETHOD":后的内容,捕获数字和小数点组成的数值部分,不管是否带双引号
  • 该方法避免了固定位置截取的缺陷,但如果JSON中存在嵌套结构或key值出现在字符串内容中,可能出现误匹配,仅作为原生JSON函数的替代方案

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:15:42