На этот раз я пришел с рекурсивным вопросом:
Я пытаюсь преобразовать
этот 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.
Спасибо за вашу помощь и поддержку !!! ...