Oracle 19/21向表插入JSON对象触发ORA-03001错误问题咨询
问题根因
两个场景触发完全相同的ORA-03001错误,和Oracle版本是否支持JSON功能无关,核心是两处基础语法错误:
- INSERT语句指定插入列时未给列名列表加括号。语法
INSERT INTO 表名 TTQ_RESULT VALUES ...会被Oracle解析为将TTQ_RESULT识别为表别名,此时SQL要求VALUES子句提供与表所有列一一匹配的值,仅传入1个值会导致解析器无法识别非法结构,抛出具有误导性的"unimplemented feature"错误。 - 非必要类型转换+键名书写不规范:
- CLOB存储JSON场景下,
to_clob(utl_raw.cast_to_raw (json_object(...)))属于完全多余的转换逻辑,Oracle 12c及以上版本的json_object原生支持直接返回CLOB类型,绕RAW类型二次转换反而容易触发类型兼容问题。 - 代码
json_object(a value '2')中键名a未加单引号,会被解析器识别为列标识符而非JSON键名,本身不符合json_object的调用语法。
- CLOB存储JSON场景下,
正确实现方法
场景1:Oracle 12c~19c版本(使用CLOB+IS JSON约束存储JSON)
建表语句保持原有定义即可,插入时直接使用json_object的RETURNING CLOB参数返回符合约束的JSON格式CLOB,不需要额外类型转换,正确插入语句如下:
INSERT INTO TABLE_TEST_QUERY_2 (TTQ_RESULT) VALUES (json_object('a' value '2' RETURNING CLOB));
插入后可直接通过TTQ_RESULT IS JSON约束校验,不会触发格式错误。
场景2:Oracle 21c及以上版本(使用原生JSON类型列存储)
建表时将TTQ_RESULT列定义为JSON类型即可,插入时直接传入json_object返回值,不需要任何类型转换,正确插入语句如下:
INSERT INTO TABLE_TEST_QUERY_2 (TTQ_RESULT) VALUES (json_object('a' value 2));
原生JSON类型列会自动校验JSON格式合法性,不需要额外加CHECK约束。
验证方式
插入完成后执行查询语句即可读取存储的JSON内容:
SELECT TTQ_RESULT FROM TABLE_TEST_QUERY_2;
不管是CLOB存储还是原生JSON类型存储,都可以直接通过Oracle提供的JSON查询函数(如json_value、json_query)读取内部字段值。
内容的提问来源于stack exchange,提问作者Pierre-olivier Gendraud
相关产品推荐
相关产品推荐

