【问题标题】:Parsing JSON in Oracle with attribute longer than 4000在 Oracle 中解析属性超过 4000 的 JSON
【发布时间】:2020-10-14 20:43:24
【问题描述】:

我正在尝试解析值超过 4000 个字符的 JSON 属性。这是我的示例 json:

[{
        "id": "268edbb5d111",
        "name": "Sample Product",
        "status": "created",
        "description": "this is sample product",
        "productCharacteristic": [{
                "name": "property_1",
                "value": "abc",
                "valueType": "String"
            }, {
                "name": "property_2",
                "value": 123,
                "valueType": "Number"
            }, {
                "name": "property_3",
                "value": "2020-05-01T04:56:07.000+00:00",
                "valueType": "Date"
            }
        ]
    }
]

这是 PL/SQL 代码:

FOR x IN (SELECT *
            FROM json_table(l_response, '$[*]'
                 COLUMNS
                 id                        varchar2(255)   PATH '$.id',
                 name                      varchar2(255)   PATH '$.name',
                 description               varchar2(255)   PATH '$.description',
                 status                    varchar2(255)   PATH '$.status',
                 productCharacteristic     varchar2(4000)  FORMAT JSON PATH '$.productCharacteristic'
                 )
            ) LOOP
  -- do something
END LOOP;

productCharacteristic 属性可能长于 4000,但将其数据类型更改为 VARCHAR2(32000) 会编译带有 ORA-00910 的包:指定长度对其数据类型而言太长,更改为 CLOB 返回 ORA-40484:JSON_TABLE 列的数据类型无效.有没有办法将整个 productCharacteristic 数组作为 JSON 传递并在循环内解析它?

谢谢。

【问题讨论】:

  • 您是否在数据库初始化参数中启用了扩展 varchar? MAX_STRING_SIZE docs.oracle.com/en/database/oracle/oracle-database/19/refrn/…
  • 如果没有其他方法,我会将其保留为最终解决方案。我不确定客户的 DBA 是否会允许这样做。
  • 作为替代方案,如果您在数据库上安装了 APEX(至少 5.1.4),您可以使用 APEX_JSON。
  • 您使用的是哪个版本的 Oracle?从 18c 开始允许 CLOB(但我认为不是 12cR1 或 12cR2)。
  • 很遗憾,APEX 没有安装。

标签: json oracle plsql


【解决方案1】:

有没有办法将整个 productCharacteristic 数组作为 JSON 传递并在循环内解析它?

这可能不是您想要的,但您可以使用 nested path 将所有数组元素展平:

FOR x IN (SELECT *
            FROM json_table(l_response, '$[*]'
                 COLUMNS
                 id                        varchar2(255)   PATH '$.id',
                 name                      varchar2(255)   PATH '$.name',
                 description               varchar2(255)   PATH '$.description',
                 status                    varchar2(255)   PATH '$.status',
                 nested path '$.productCharacteristic[*]'
                   COLUMNS  (
                     product_name          varchar2(255)   PATH '$.name',
                     product_value         varchar2(4000)  PATH '$.value',
                     product_value_type    varchar2(255)   PATH '$.valueType'
                   )
                 )
            ) LOOP
  -- do something
  dbms_output.put_line(x.id || ' ' || x.product_name || ' ' || x.product_value);
END LOOP;

db<>fiddle

【讨论】:

  • 是的,嵌套路径也是我尝试过的解决方案之一,它不是我所需要的,但我会让它工作的。计划将数据库升级到 19c(不是现在,可能在几个月后),所以我将能够使用 CLOB 作为 JSON 数据类型,直到那时嵌套路径就可以了。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 2016-07-01
  • 2011-01-31
相关资源
最近更新 更多