mysql error 1064存储过程将json值提取到表中的特定列中

rhfm7lfc  于 2021-06-25  发布在  Mysql
关注(0)|答案(1)|浏览(476)

我想将可变长度的json数据提取到现有表中,但出现以下错误:
错误代码:1064。sql语法有错误;查看与mysql服务器版本相对应的手册,了解使用begindeclarelenint;声明i int;声明mykey varchar(60);在第2行声明myvalue
有人知道如何解决这个错误,或者如何将可变长度的json数据提取到现有的表中吗?
这是我的密码:

drop procedure if exists wk; 
delimiter // 
create procedure wk(tb varchar(60), myjson json)   
begin
SET @LEN= (select JSON_LENGTH(myjson));
set @i=1;
set @mykey='initial';
set @myvalue='initial';
set @thekeys= (select JSON_keys(myjson));
set @mysql_1=concat("insert into ",tb," (");
set @mysql_2='(';
while @i < @len*2 do
select 3;
set @mykey = (select substring(substring_index(@thekeys,'"',@i+1),length(substring_index(@thekeys,'"',@i))+2));
set @myvalue = (select json_extract(myjson,concat('$.',@mykey)));
set @mysql_1= concat(@mysql, @mykey,","); 
set @mysql_2= concat(@mysql_2, @myvalue,",") ;
set @i =@i+2
end while;

set @mysql = concat(substring(@mysql_1,-1),") values ", substring(@mysql_2,-1)," );");

PREPARE stmt FROM @mysql;
EXECUTE stmt;

end
  //
delimiter ;

call wk('actor','{"actor_id": 1, "first_name": "NICK"}');
hxzsmxv2

hxzsmxv21#

导致这些错误的直接原因似乎是程序的第二行和第三行中的一些非打印字符—直接在后面 delimiter // ,也在 create procedure wk(tb varchar(60), myjson json) .
一旦你清除了这些字符,你会得到另一个错误,这将告诉你有另一个语法错误之前 end while (后面缺少分号) set @i =@i+2 ).
mysql通常非常善于让您确切地知道在试图解析语句时它从哪里开始遇到问题,问题就在突出显示的文本之前。这里,它说问题从“开始”开始,问题就在它前面。
排除错误后,您的过程将运行并输出“3”两次。但是,@mysql将为null,并且不会准备和执行任何语句。
我不打算试着调试代码,因为我认为你把问题复杂化了。当mysql有非常好的工具为您做的时候,您似乎正在尝试编写自己的例程来解析json的某些部分。设置@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"}');

相关问题