mysql-遍历所有行并更新json数组中的所有对象

时间:2020-09-23 10:51:56

标签: mysql json loops

对于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}
    ]
}

为什么会这样?

1 个答案:

答案 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 ;
相关问题