MySQL update specific JSON objects in an array

I am struggling to find a way to update specific JSON objects in a array within JSON-type field in MySQL. Let's say I have the following object:

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

How can I update all objects in the parrot array that have the volume value as loud?

I know I could use the JSON_SET or JSON_REPLACE functions to change/update a specific object if the position of the object is known. For example something like:

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

However I don't know the positions of the objects and also this doesn't update all in the parrot array that have the volume value as loud?

Any suggestions?


One option:

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');

See db-fiddle.