使用 Oracle Database 19c 企业版中的 Json_transform() 函数更新包含 Json 数组的 Json 列

Updating a Json column that contains a JsonArray using Json_transform() function in Oracle Database 19c Enterprise Edition

我有一个 table 可以保存 USER 数据。

这是我的 table 结构:

CREATE TABLE "USERS"
(
    "ID" NUMBER(16,0) PRIMARY KEY,
    "USER_NAME" VARCHAR2(85) UNIQUE NOT NULL,
    "IDENTIFICATION_TYPE" NUMBER(3,0) NOT NULL REFERENCES IDENTIFICATION_TYPES(ID),
    "IDENTIFICATION_CODE" VARCHAR2(24) NOT NULL,
    "TRADING_CODE" VARCHAR2(85) NULL,
    "PASSWORD" VARCHAR2(48) NOT NULL,
    "SALT" VARCHAR2(24) NOT NULL,
    "FLAGS" NUMBER(3) NOT NULL,
    "PROFILE" NCLOB NOT NULL CONSTRAINT profile_json CHECK ("PROFILE" IS JSON),
    "SETTINGS" NCLOB NOT NULL CONSTRAINT settings_json CHECK ("SETTINGS" IS JSON),   
  UNIQUE(IDENTIFICATION_TYPE,IDENTIFICATION_CODE)
);

如您所见,我有一个名为 SETTINGS 的 Json 列。

并且将保留在此列中的数据如下所示:

{
  "lang" : "fa-IR",
  "cols" : [],
  "watch_lists" :
  {
    "list_1" : [5,6,7],
    "list_2" : [8,9],
    "list_3" :[1,2,3]
  }
}

现在我的应用程序收到了 watch_lists 的更新列表,我想将其替换为当前列表。

起初经过一些研究,我可以使用 JSON_MERGEPATCH() 函数编写以下查询:

UPDATE USERS 
SET SETTINGS = JSON_MERGEPATCH(SETTINGS, '{ "watch_lists": { "liist_1": [4,5],"liist_2": [1,3,5] }}' returning clob pretty)
WHERE USER_NAME = 'admin'

但是我发现JSON_MERGEPATCH()会将更新后的列表与当前列表合并,但我需要替换它,最后我明白我需要使用JSON_TRANSFORM()函数来替换列表,所以我写了以下查询:

UPDATE USERS 
SET SETTINGS = JSON_TRANSFORM(SETTINGS,
               SET '$.watch_lists' =
                   '{ "liist_1": [4,5],"liist_2": [1,3,5] }'
                   FORMAT JSON)
WHERE USER_NAME = 'admin'

但现在它抛出一个异常:

SQL Error [1747] [42000]: ORA-01747: invalid user.table.column, table.column, or column specification

我找不到这个错误的原因来解决它。

谁能帮帮我?

任何帮助将不胜感激!!

似乎 JSON_TRANSFORM 从 21c 版本开始可用(并且在 19c 的更高版本中被 向后移植 )。

无论如何,您可以使用 JSON_MERGEPATH 两步 方法。

先重置属性,然后将其设置为新值:

UPDATE USERS 
SET SETTINGS = JSON_MERGEPATCH(SETTINGS,              
                   '{ "watch_lists": null}'
                  )
WHERE USER_NAME = 'admin'
;
UPDATE USERS 
SET SETTINGS = JSON_MERGEPATCH(SETTINGS,              
                   '{ "watch_lists": { "liist_1": [4,5],"liist_2": [1,3,5] }}'
                  )
WHERE USER_NAME = 'admin'
;