对于mysql 5.7,我有一个表copy_jobs
,其列的json类型为job_configs
。
job_configs
具有属性configurations
,它是一个对象数组。
job_configs
中的数据示例:
{"configurations": [
{
"role": "Introduction", "role_id": 1, "employee_id": 1,
"first_payment": "15.63", "second_payment": "46.88",
"employee_number": "00001", "employee_last_name": "Mendes",
"first_payment_made": false, "employee_first_name": "Mario",
"second_payment_made": false, "total_bonus_percentage": 25
}, {
"role": "P & D", "role_id": 2, "employee_id": 2,
"first_payment": "12.50", "second_payment": "37.50",
"employee_number": "00002", "employee_last_name": "Parker",
"first_payment_made": false, "employee_first_name": "Shaun",
"second_payment_made": false, "total_bonus_percentage": 20
}
]}
我需要运行一个迁移,将向表的每一行的"fumbled": false
数组中的每个对象添加属性fumblesCaught: []
和configurations
。
我以为
UPDATE copy_jobs
SET job_configs = JSON_SET(job_configs, '$.configurations[*].fumbled', false);
至少可以添加"fumbled": false
,但这会返回错误消息:In this situation, path expressions may not contain the * and ** tokens.
是否有一种方法可以运行单个命令,从而将两个新属性添加到configurations
数组中的每个对象中?
还是我需要创建一个我可以调用的过程,该过程将获取所有行,并通过configurations
对象的每一行循环,然后一个接一个地将两个新属性添加到对象中?
编辑:
@wchiquito发表评论后,我创建了一个程序,认为这可以工作。
CREATE PROCEDURE updateRoleConfig()
BEGIN
DECLARE counter Int DEFAULT 0;
DECLARE totalRows Int;
SELECT COUNT(*) INTO totalRows FROM copy_jobs;
SET totalRows = totalRows + 1;
WHILE counter < totalRows DO
SET @offset = counter;
PREPARE getRowSql FROM 'SELECT job_configs INTO @jsonConfigs FROM copy_jobs LIMIT 1 OFFSET ?';
EXECUTE getRowSql USING @offset;
SELECT concat('selected row is ', @jsonConfigs);
UPDATE copy_jobs SET job_configs = JSON_SET(job_configs, '$.configurations', CAST(
REPLACE(
JSON_EXTRACT(@jsonConfigs, '$.configurations'),
'}',
', "fumbled": false, "fumblesCaught": []}') AS JSON
)
);
SET counter = counter + 1;
END WHILE;
END
但是,这导致使用单个对象覆盖所有行configurations
数组,从而导致所有行都相同。
奇怪的是,@jsonConfigs
的输出始终是对象的值覆盖所有其他对象,这恰好是表第一行中的configurations
数组的值。
{"configurations": [
{
"role": "Introduction", "role_id": 1, "employee_id": 1,
"first_payment": "15.63", "second_payment": "46.88",
"employee_number": "00001", "employee_last_name": "Mendes",
"first_payment_made": false, "employee_first_name": "Mario",
"second_payment_made": false, "total_bonus_percentage": 25}
]
}
为什么会这样?
答案 0 :(得分:0)
最后我也通过将ID存储在变量中,然后使用该ID更新并获取json来使其工作。
DELIMITER //
CREATE PROCEDURE updateRoleConfig()
BEGIN
DECLARE counter Int DEFAULT 0;
DECLARE totalRows Int;
SELECT COUNT(*) FROM copy_jobs INTO totalRows;
SET totalRows = totalRows + 1;
SET counter = 0;
WHILE counter < totalRows DO
SET @offset = counter;
SELECT concat('offset is ', @offset);
SELECT concat('counter is ', counter);
PREPARE getIdSql FROM 'SELECT id FROM copy_jobs LIMIT 1 OFFSET ? INTO @rowId';
EXECUTE getIdSql USING @offset;
PREPARE getJsonSql FROM 'SELECT job_configs FROM copy_jobs WHERE id=? INTO @jsonConfigs';
EXECUTE getJsonSql USING @rowId;
SELECT concat('selected row is ', @jsonConfigs);
SELECT concat('selected row id ', @rowId);
SET @json = JSON_SET(@jsonConfigs, '$.configurations', CAST(
REPLACE(
JSON_EXTRACT(@jsonConfigs, '$.configurations'),
'}',
', "fumbled": false, "fumblesCaught": []}') AS JSON
)
);
UPDATE copy_jobs SET job_configs = @json WHERE id = @rowId;
SET counter = counter + 1;
END WHILE;
END//
DELIMITER ;