MySQL更新数组中的特定JSON对象

时间:2018-01-31 21:48:57

标签: mysql json mysql-5.7

我正在努力寻找一种方法来更新MySQL中JSON类型字段内的数组中的特定JSON对象。让我们说我有以下对象:

SET @j = '{
 "cat": "meow", 
 "dog": "woof", 
 "parrot": [
   {"volume": "quiet", "says": "hello"}, 
   {"volume": "loud", "says": "polly"},
   {"volume": "loud", "says": "cracker"}
  ]
}';

如何更新 parrot 数组中音量值为响亮的所有对象?

我知道如果知道对象的位置,我可以使用JSON_SET或JSON_REPLACE函数来更改/更新特定对象。例如:

UPDATE T1 SET @J = JSON_SET(@j, '$.parrot[1].says', 'pretty bird');

但是我不知道对象的位置,而且这并没有在 parrot 数组中更新所有音量值响亮

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

一个选项:

DROP PROCEDURE IF EXISTS `sp_update_json`;

DELIMITER //

CREATE PROCEDURE `sp_update_json`(
  `json` JSON,
  `value` VARCHAR(255)
)
BEGIN
  DECLARE `array_objects` JSON DEFAULT
    REPLACE(JSON_SEARCH(`json`,
                'all',
                'loud',
                NULL,
                '$.parrot[*].volume'
               ), 'volume', 'says');
  DECLARE `max_objects` INT UNSIGNED DEFAULT 
    JSON_LENGTH(`array_objects`);
  DECLARE `current_object` INT UNSIGNED DEFAULT 0;
  WHILE `current_object` < `max_objects` DO
    SET `json` := JSON_REPLACE(`json`, 
                           JSON_UNQUOTE(                             
                             JSON_EXTRACT(
                               `array_objects`,
                               CONCAT('$[', `current_object`, ']')
                             )
                           ), `value`);
    SET `current_object` := `current_object` + 1;
  END WHILE;
  SELECT `json`;
END//

DELIMITER ;

SET @`j` := '
{
  "cat": "meow", 
  "dog": "woof", 
  "parrot": [
    {"volume": "quiet", "says": "hello"}, 
    {"volume": "loud", "says": "polly"},
    {"volume": "loud", "says": "cracker"}
  ]
}';

CALL `sp_update_json`(@`j`, 'pretty bird');

请参阅db-fiddle