Непосредственной причиной ошибок, по-видимому, являются некоторые непечатаемые символы во второй и третьей строках вашей процедуры - непосредственно после delimiter //
, а также после закрывающей скобки create procedure wk(tb varchar(60), myjson json)
.
Как только вы очистите эти символы, вы получите еще одну ошибку, которая скажет вам, что есть еще одна синтаксическая ошибка непосредственно перед end while
(отсутствует точка с запятой после set @i =@i+2
).
MySQL, как правило, очень хорошо сообщает вам, где именно он начинает сталкиваться с проблемами при попытке проанализировать ваши операторы, причем проблема непосредственно предшествует выделенному тексту. Здесь говорится, что проблема начинается с «начала», а проблема - непосредственно перед ней.
После устранения ошибок ваша процедура будет запущена и выведет «3» дважды. Однако @mysql будет иметь значение NULL, и никакие инструкции не будут подготовлены и выполнены.
Я не собираюсь пытаться отлаживать код, потому что я думаю, что вы слишком усложняете проблему. Похоже, вы пытаетесь написать свои собственные подпрограммы для разбора частей JSON, когда MySQL имеет совершенно хорошие инструменты, чтобы сделать это для вас. Установка @mykey является показательным примером, где вы можете использовать индекс непосредственно в массиве @thekeys вместо использования подстроки для анализа ключей, например.
mysql> SET @thekeys = JSON_KEYS('{"actor_id": 1, "first_name": "NICK"}');
mysql> SET @mykey = JSON_UNQUOTE(JSON_EXTRACT(@thekeys, '$[1]'));
mysql> SELECT @mykey;
+------------+
| @mykey |
+------------+
| first_name |
+------------+
Если вы используете встроенные функции JSON, вы можете значительно упростить код, и вам остается только беспокоиться о том, соответствуют ли ваши пары значений ключей определенным именам столбцов и типам данных.
, например
DELIMITER //
DROP PROCEDURE IF EXISTS wk //
CREATE PROCEDURE wk(tbl VARCHAR(64), myjson JSON)
BEGIN
DECLARE i INT DEFAULT 0;
SET @keys = '';
SET @vals = '';
WHILE i < JSON_LENGTH(myjson) DO
SET @mykey = JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(myjson), CONCAT('$[', i, ']')));
SET @myval = JSON_UNQUOTE(JSON_EXTRACT(myjson, CONCAT('$.', @mykey)));
SET @keys = CONCAT(@keys, IF(CHAR_LENGTH(@keys) > 0, ',', ''),
CONCAT('`', @mykey, '`'));
SET @vals = CONCAT(@vals, IF(CHAR_LENGTH(@vals) > 0, ',', ''),
CONCAT('''', @myval, ''''));
SET i = i + 1;
END WHILE;
SET @sql = CONCAT('INSERT INTO `', tbl , '`(', @keys, ') VALUES (', @vals, ');');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
CALL wk('actor','{"actor_id": 1, "first_name": "NICK"}');