如何在MySQL的数组中插入JSON对象?

问题描述

我目前被分配一项任务,将我们的活动非标准化表转换为标准化表。我们决定使用数据库触发器来促进批量迁移和成功的数据更改,直到我们停止使用旧表为止。

下面是我们旧表的结构和示例:

SELECT * FROM TabHmIds;

ID  EntitlementID   TabId   HmId
1   101             201     301
2   102             202     302

新表的所需结构和示例应类似于:

SELECT * FROM tab_integration;
id  tab_id  integration_id  Metadata
1   201     1               { "paid_id": {"entitlement_id": 101,"id": 301} }
2   202     1               { "paid_id": {"entitlement_id": 202,"id": 302} }

以下是到目前为止我在INSERT触发器中所做的事情:

CREATE TRIGGER tab_integration_after_insert AFTER INSERT ON `TabHmIds` 
FOR EACH ROW 
BEGIN 

DECLARE var_Metadata JSON;
DECLARE var_new_Metadata JSON;
DECLARE var_hm_Metadata JSON;
DECLARE var_integration_id INT(11);

SELECT
  Metadata,integration_id INTO var_Metadata,var_integration_id
FROM
  `go`.`tab_integration` gti
WHERE
  gti.`tab_id` = NEW.`TabId`;

SET var_hm_Metadata = JSON_OBJECT('entitlement_id',NEW.`EntitlementId`,'id',NEW.`HmId`);

IF var_integration_id = 1 THEN 
    
    IF var_Metadata IS NULL THEN
        SET var_new_Metadata = JSON_OBJECT('paid_id',var_hm_Metadata);
        
    ELSE
        SET @paid_id = JSON_UNQUOTE(JSON_EXTRACT(var_Metadata,'$.paid_id'));        
        SET var_new_Metadata = JSON_ARRAY_APPEND(var_Metadata,'$.paid_id',var_hm_Metadata);

    END IF;
    
END IF;

UPDATE `tab_integration` gti SET `Metadata` = var_new_Metadata WHERE `tab_id` = NEW.`TabId`;

END

但是,我得到的是这样:

SELECT * FROM tab_integration;

id  tab_id  integration_id  Metadata
1   201     1               { "paid_id": "{\"entitlement_id\": 101,\"id\": 301}" }
2   202     1               { "paid_id": "{\"entitlement_id\": 202,\"id\": 302}" }

从上表中,JSON对象被解析为STRING。我知道JSON_OBJECT将传递的值解析为字符串。因此,我使用JSON_UNQUOTE(JSON_EXTRACT(...))将paid_id路径值转换为JSON,但未将其解析为JSON。我还尝试了JSON_MERGE_PRESERVE将JSON对象放在paid_id路径下,但最终得到了:

{“paid_id”: [],“entitlement_id”: 101,“id”: 301 }

我还尝试使用JSON_TABLE将JSON数组放入临时表中,并修改该临时表中的值,然后使用JSONARRAYAGG将该临时表转换为JSON。但是,即使我直接从网上复制了示例,Workbench仍然说我的语法有误。

我也尝试过将格式正确的字符串转换为JSON,但是Workbench还会引发语法错误。 我花了一个星期的时间来解决MysqL中的这种数据结构。

数据库脚本并不是我的强项,我对MysqL的JSON函数还是陌生的。预先感谢那些会回答的人。

如果需要,我的MysqL Workbench版本为 10.4.13-MariaDB 。但是该脚本应在MysqL 5.7 中工作。

解决方法

我找到了解决问题的方法。

在插入新的JSON数据之前,我将其解析为CHAR并替换了使其成为字符串的字符。我做了以下工作,而且有效!

# After performing the needed JSON manipulations,cleanse the JSON string to JSON.

SET var_new_metadata = CAST(var_new_metadata AS CHAR);

SELECT REPLACE(REPLACE(REPLACE(var_new_metadata,'\\',''),'\"\{','{'),'\}\"','}') INTO var_new_metadata;

清除数据后,UPDATE调用仍然有效,并尝试进行一些JSON操作,是的,仍然有效!