Oracle19c使用JSON_TRANSFORM更新含JSON数组的JSON列报ORA-01747错误如何解决
ORA-01747错误原因及解决方案
错误根因
ORA-01747报错属于Oracle版本兼容性问题:JSON_TRANSFORM的SET子句直接赋值JSON字面量加FORMAT JSON的语法是Oracle 21c才新增的特性,如果你使用18c、19c等更低的长期支持版本,SQL解析器无法识别该语法,会判定为无效列定义抛出错误。
可选解决方案
方案1:全版本兼容方案(推荐)
采用JSON_REMOVE+JSON_INSERT组合实现全量替换,先删除原有watch_lists节点,再插入新节点,12cR2及以上版本均可运行:
UPDATE USERS SET SETTINGS = JSON_INSERT( JSON_REMOVE(SETTINGS, '$.watch_lists'), '$.watch_lists', JSON('{ "liist_1": [4,5],"liist_2": [1,3,5] }') ) WHERE USER_NAME = 'admin';
该方案逻辑明确,不会残留原有watch_lists下的子属性,完全满足全量替换需求。
方案2:21c及以上版本修正写法
如果使用21c及更高版本,调整JSON_TRANSFORM语法,将JSON值用JSON()函数包裹即可:
UPDATE USERS SET SETTINGS = JSON_TRANSFORM(SETTINGS, SET '$.watch_lists' = JSON('{ "liist_1": [4,5],"liist_2": [1,3,5] }') ) WHERE USER_NAME = 'admin';
方案3:基于JSON_MERGEPATCH实现全量替换
利用JSON Merge Patch规范中赋值为null即删除节点的规则,也可以实现全量替换效果:
UPDATE USERS SET SETTINGS = JSON_MERGEPATCH( SETTINGS, '{ "watch_lists": null, "watch_lists": { "liist_1": [4,5],"liist_2": [1,3,5] }}', RETURNING CLOB ) WHERE USER_NAME = 'admin';
额外提示
示例中新的watch_lists键名写为liist_1、liist_2(多了一个字母i),如果是笔误要覆盖原有list_1、list_2,请修正键名避免业务逻辑不符合预期。
内容的提问来源于stack exchange,提问作者Sobhan
相关产品推荐
相关产品推荐

