mysql - 如果存在另一个属性,则删除 MySQL JSON 属性
问题描述
在我的数据库中,有许多产品行带有名为“代码”的 JSON 列,我想:
- 删除
default
“掩码”属性旁边的所有属性, - 或者如果掩码存在于默认区域(不是单个默认字段)。
{
...
"access": {
...
},
"layouts": [
{
...
"grid": [
{
...
"default": "...",
...
},
{
...
},
{
...
},
{
...
},
{
...
"default": "...",
"mask": "...",
...
}
]
}
],
...
}
我该怎么做?
解决方案
很多人会说:在 MySQL 之外的某种脚本中执行此操作。我会同意,但其中的乐趣在哪里。
但是,您将需要一个存储的例程才能执行您想要的操作。问题是JSON_REMOVE
不接受通配符。
根据您的要求,我提出了以下例程(请测试并适应!):
DROP PROCEDURE IF EXISTS remove_defaults;
DELIMITER $$
CREATE PROCEDURE remove_defaults()
BEGIN
DECLARE done BOOL;
DECLARE i INT;
DECLARE vID INT;
DECLARE vGrid JSON;
DECLARE vDoc JSON;
DECLARE cur CURSOR FOR SELECT id, doc FROM t1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
SET done = FALSE;
REPEAT
FETCH cur INTO vID, vDoc;
-- get the 'grid' array from the JSON document
SET vGrid = JSON_EXTRACT(vDoc, '$.grid');
SET i = 0;
WHILE i < JSON_LENGTH(vGrid) DO
-- check if this grid entry has 'mask' attribute
IF JSON_CONTAINS_PATH(vGrid, 'one', CONCAT('$[',i,'].mask')) = 1 THEN
-- it does have 'mask', so we remove the default
SET vGrid = JSON_REMOVE(vGrid, CONCAT('$[',i,'].default'));
END IF;
SET i = i + 1;
END WHILE;
-- update the original JSON document with the new 'grid'
UPDATE t1 SET doc = JSON_REPLACE(doc, '$.grid', vGrid) WHERE id = vID;
UNTIL done END REPEAT;
CLOSE cur;
END $$
这使用简化表:
CREATE TABLE t1
(
id INT AUTO_INCREMENT PRIMARY KEY,
doc JSON
);
使用如下测试数据:
+----+-----------------------------------------------------------+
| id | doc |
+----+-----------------------------------------------------------+
| 1 | {"grid": [{"mask": "foo", "default": 1}, {"default": 2}]} |
| 2 | {"grid": [{"mask": "bar"}, {"default": 3}]} |
+----+-----------------------------------------------------------+
这将导致:
+----+---------------------------------------------+
| id | doc |
+----+---------------------------------------------+
| 1 | {"grid": [{"mask": "foo"}, {"default": 2}]} |
| 2 | {"grid": [{"mask": "bar"}, {"default": 3}]} |
+----+---------------------------------------------+
但是,如果您对存储例程感到不舒服,或者您无法将其添加到您的架构中,您可能确实在 MySQL 之外执行此操作。
推荐阅读
- c# - 为什么我无法在 VS 2013 中放置调试点?
- php - 单击按钮以显示数据库中的下一条记录(限制)
- scikit-learn - 直方图的长度因情况而异
- asp.net - 如何禁用 asp.net Web 应用程序的自动完成文本框
- sql - 列中的错误 - Postgres(psycopg2.ProgrammingError:列“sales_ind”的类型为整数,但表达式的类型为字符变化)
- python - 根据Python中的列表重命名文件夹中的图像
- powershell - 使用 Powershell 签署带有证书的文件
- android - 即使删除了应用程序,Cordova 应用程序中的 Web 存储也会保留
- javascript - 如何通过 javascript 确定 MCC 和 MNC 设备?
- javascript - 在提交按钮中显示发送电子邮件状态