问题描述
我目前被分配一项任务,将我们的活动非标准化表转换为标准化表。我们决定使用数据库触发器来促进批量迁移和成功的数据更改,直到我们停止使用旧表为止。
下面是我们旧表的结构和示例:
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操作,是的,仍然有效!