Oracle 12c JSON TABLE 解析错误处理

Posted

技术标签:

【中文标题】Oracle 12c JSON TABLE 解析错误处理【英文标题】:Oracle 12c JSON TABLE parsing error handling 【发布时间】:2020-04-14 11:38:42 【问题描述】:

是否可以在使用JSON_TABLE 解析无效 JSON 时处理错误? 例如下面的查询工作

SELECT *
FROM 
JSON_TABLE(
    '["productCode":"AD","serials":["id":"234242343","isPrimary":true],"productCode":"BC","serials":["id":"23345345","isPrimary":true]]'
    , '$[*]'
    columns(
        productCode varchar2 PATH '$.productCode' NULL ON ERROR,
        serials varchar2 format JSON PATH '$.serials' NULL ON ERROR
    )
);

上面的输出如下:

|PRODUCTCODE | SERIALS                              |
|---------------------------------------------------|
|AD          |["id":"234242343","isPrimary":true] |
|BC          |["id":"23345345","isPrimary":true]  |

在上面的例子中,输入的 JSON 是有效的,但是,在我的例子中,不能保证它是从另一个日志表中获取的。

如果遇到无效的 JSON,我希望查询忽略。

【问题讨论】:

【参考方案1】:

简单的方法是将数据转移到带有检查约束的新表中,以检查源表中的数据是否符合JSON 格式作为Oracle 12c+ 用户。

如果格式为假,则该行将不会插入到该新表中,例如

CREATE TABLE tab_new (
  id      INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  jsdata  VARCHAR2(500),
  CONSTRAINT json_chk CHECK (jsdata IS JSON)
);

BEGIN
  FOR C IN ( SELECT jsdata FROM tab_old )
  LOOP
  BEGIN
     INSERT INTO tab_new(jsdata) VALUES(c.jsdata) ;
   EXCEPTION
     WHEN OTHERS THEN IF SQLCODE = -2290 THEN 
                       INSERT INTO tab_error(jsdata) VALUES(c.jsdata) ;
                      END IF;
  END;
  END LOOP;
  COMMIT;
END;
/

Demo

【讨论】:

【参考方案2】:

您可以使用is json 条件过滤掉无效的JSON:

create table t (
  what varchar2(20),
  c1   varchar2(500)
);

insert into t 
  values ( 'valid JSON', '["productCode":"AD","serials":["id":"234242343","isPrimary":true],"productCode":"BC","serials":["id":"23345345","isPrimary":true]]' );
insert into t 
  values ( 'invalid JSON', '"productCode":"AD","serials":["id":"234242343","isPrimary":true],"productCode":"BC","serials":["id":"23345345","isPrimary":true]]' );
commit;

select what from t
where  c1 is json;

WHAT         
valid JSON   

但这是不必要的:json_table 已经忽略了无效文档!

SELECT what, j.*
FROM   t, JSON_TABLE(
    c1, '$[*]'
    columns(
      productCode varchar2 PATH '$.productCode' NULL ON ERROR,
      serials varchar2 format JSON PATH '$.serials' NULL ON ERROR
    )
) j;

WHAT          PRODUCTCODE    SERIALS                                 
valid JSON    AD             ["id":"234242343","isPrimary":true]    
valid JSON    BC             ["id":"23345345","isPrimary":true]  

您可以使用 on error 子句对无效 JSON 强制出错:

SELECT what, j.*
FROM   t, JSON_TABLE(
    c1, '$[*]'
    error on error
    columns (
      productCode varchar2 PATH '$.productCode' NULL ON ERROR,
      serials varchar2 format JSON PATH '$.serials' NULL ON ERROR
    )
) j;

ORA-40441: JSON syntax error

【讨论】:

以上是关于Oracle 12c JSON TABLE 解析错误处理的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 12c 无法识别 JSON 类型

oracle sql中的JSON_TABLE未捕获嵌套的json数据

将动态 JSON 解析为 Oracle 表

Oracle 12c - 从视图中获取 IMPORT_TABLE_STATS

Oracle 12c连接时报错ORA-28040问题解决方法

MySql 5.7对json_table()函数的一次变通替代