Мариадб рекурсивная процедура в JSON - PullRequest
0 голосов
/ 22 февраля 2019

На этот раз я пришел с рекурсивным вопросом:

Я пытаюсь преобразовать

этот json:

["buyer_name", ["first_name", "aaa", "second_name", "bbb"]]

в этот сериализованный массив php:

s:10:"buyer_name";a:2:{s:10:"first_name";s:3:"aaa";s:11:"second_name";s:3:"bbb";};

С помощью процедуры MariaDB.

Я строю эту простую процедуру в MariaDB.

-- ----------------------------
-- Function getSerializedString
-- ----------------------------

DROP PROCEDURE IF EXISTS `getSerializedString`;
CREATE PROCEDURE `getSerializedString`(IN __input_string TEXT, OUT __output TEXT)
   LANGUAGE SQL DETERMINISTIC MODIFIES SQL DATA SQL SECURITY DEFINER 
   COMMENT 'Procedure returns a serialized __input_string with his __input_value.'
BEGIN
   /*
      Procedure returns a serialized __input_string with his __input_value.
   */
   DECLARE i INT UNSIGNED DEFAULT 0;
   IF (__output IS NULL) THEN
      SET __output = '';
   END IF;
   SET GLOBAL max_sp_recursion_depth = 255;

   WHILE (i < (JSON_LENGTH(__input_string))) DO
      IF (JSON_EXTRACT(__input_string, CONCAT('$[' , i, ']')) REGEXP '^[0-9]+$') THEN
         SET __output = CONCAT(__output, CONCAT('i', ':', JSON_EXTRACT(__input_string, CONCAT('$[' , i, ']')), ';'));
      ELSEIF (CHAR_LENGTH(JSON_EXTRACT(__input_string, CONCAT('$[' , i, ']'))) - CHAR_LENGTH(REPLACE(JSON_EXTRACT(__input_string, CONCAT('$[' , i, ']')), '.', '')) = 1) THEN
         SET __output = CONCAT(__output, CONCAT('d', ':', JSON_EXTRACT(__input_string, CONCAT('$[' , i, ']')), ';'));
      ELSE
         SET __output = CONCAT(__output, CONCAT('s', ':', (CHAR_LENGTH(REPLACE(JSON_EXTRACT(@__input_string, CONCAT('$[' , i, ']')), '"', ''))), ':', JSON_EXTRACT(__input_string, CONCAT('$[' , i, ']')), ';'));
      END IF;

      IF (JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')) REGEXP '^[0-9]+$') THEN
         SET __output = CONCAT(__output, CONCAT('i', ':', JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), ';'));
      ELSEIF (CHAR_LENGTH(JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']'))) - CHAR_LENGTH(REPLACE(JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), '.', '')) = 1) THEN
         SET __output = CONCAT(__output, CONCAT('d', ':', JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), ';'));
      ELSEIF ((REPLACE(JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), '.', '')) NOT REGEXP '^[0-9]+$') THEN
         IF (SUBSTRING(JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), 1, 1) = '[' AND SUBSTRING(JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), CHAR_LENGTH(JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']'))), 1) = ']') THEN
            CALL `getSerializedString`(JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), @res);
            SET __output = CONCAT(__output, CONCAT('a', ':', (JSON_LENGTH(JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']'))) DIV 2), ':', '{', @res, '}'));
         ELSE
            SET __output = CONCAT(__output, CONCAT('s', ':', (CHAR_LENGTH(REPLACE(JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), '"', ''))), ':', JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), ';'));
         END IF;
      ELSE
         SET __output = CONCAT(__output, CONCAT('s', ':', (CHAR_LENGTH(REPLACE(JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), '"', ''))), ':', JSON_EXTRACT(__input_string, CONCAT('$[' , (i + 1), ']')), ';'));
      END IF;
      SET i = i + 2;
   END WHILE;

END;

Сейчас:

Если я запускаю процедуру столько такая запись, как эта:

["first_name", "aaa", "age", 25]

Это дает правильный результат.

Проблема возникает, когдапроцедура обнаруживает вложенный массив, например: ["customer_name", ["first_name", "aaa", "age", 25]]

и рекурсивно вызывает функцию с вложенным массивом, в этом случае:["first_name", "bbb", "age", 30]

MariaDB возвращает нулевое или пустое значение.

Есть ли какая-либо ошибка, вызывающая таким образом рекурсивную процедуру?

Если процедура обнаруживает, что нет вложенного массива, она работает просто отлично.

Кстати: я считаю, что массив json всегда имеет пару имя: значение.Вот почему WHILE (i) увеличивается на 2.

Спасибо за вашу помощь и поддержку !!! ...

...