MySQL8 json 有效负载不接受 json 字符串作为元素的值

MySQL8 json payload does not accept json string as value for element

提问人:eetaSanglo 提问时间:11/15/2023 最后编辑:eetaSanglo 更新时间:11/15/2023 访问量:26

问:

我有一个存储过程(请参阅下面的stored_procedure_1代码),该过程需要将 json 作为参数传递并将该数据插入到表中。


-- stored_procedure_1:

DELIMITER \\

DROP PROCEDURE IF EXISTS my_test_procedure \\

CREATE PROCEDURE my_test_procedure(my_payload JSON)

BEGIN

    INSERT INTO my_test_table (id, ud)
    SELECT jt.id,
           jt.ud
    FROM JSON_TABLE(my_payload, '$[*]' columns (
        id int path '$.id',
        ud json path '$.ud'
        )) AS jt;
END \\

DELIMITER ;

-- 表 DDL:

CREATE TABLE my_test_table
(
    id int,
    ud varchar(255),
    PRIMARY KEY (id)
);

使用以下调用调用过程(请参阅下面的call_1),该调用将 json 字符串作为其中一个元素的值会产生错误(请参阅下面的error_1响应)。

-- call_1:

CALL my_test_procedure('[{"id":1,"ud":"{\"1\":5,\"2\":6,\"3\":7}"}]');

-- error_1: 错误代码:3140。无效的 JSON 文本:“对象成员后缺少逗号或”}“,位于列”.my_payload“值的第 17 位。

将该值作为 json 调用(请参阅下面的call_2)按预期工作。

-- call_2:

CALL my_test_procedure('[{"id":1,"ud":{\"1\":5,\"2\":6,\"3\":7}}]'); -- OR
CALL my_test_procedure('[{"id":1,"ud":{"1":5,"2":6,"3":7}}]');

在MySQL代码中寻找解决方法的建议(考虑传递的有效负载的格式无法更改)。

存储过程 反序列化 mysql-8.0 json 表

评论


答:

1赞 Nick 11/15/2023 #1

问题在于字符串内部的转义;当字符串被MySQL解释时,被解释为(参见手册)。例如:"\""

SELECT '[{"id":1,"ud":"{\"1\":5,\"2\":6,\"3\":7}"}]'

输出:

[{"id":1,"ud":"{"1":5,"2":6,"3":7}"}]

这不是有效的 JSON。要在MySQL解释时成为有效的JSON,您需要在之前进行转义(即,MySQL随后将其解释为):\"\\"\"

SELECT '[{"id":1,"ud":"{\\"1\\":5,\\"2\\":6,\\"3\\":7}"}]'

输出:

[{"id":1,"ud":"{\"1\":5,\"2\":6,\"3\":7}"}]

然后,这将与您的程序一起使用:

CALL my_test_procedure('[{"id":1,"ud":"{\\"1\\":5,\\"2\\":6,\\"3\\":7}"}]');
SELECT *
FROM my_test_table

输出:

id  ud
1   "{\"1\":5,\"2\":6,\"3\":7}"

评论

0赞 eetaSanglo 11/16/2023
谢谢你的解释,@Nick。我现在更明白为什么我的call_1出错了。回到我在帖子中的陈述“在MySQL代码中寻找解决方法的建议(考虑传递的有效负载的格式不能更改)”,您对MySQL例程中的解决方法有建议吗(考虑到有效负载格式无法更改)?
0赞 Nick 11/16/2023
@eetaSanglo我不确定是否有任何简单的方法可以解决这个问题,而无需手动解析整个输入。但我有点困惑,你是怎么得到这样的字符串的;我本来以为消息来源会给你一些带有转义 \ 的东西。字符串如何进入MySQL查询?您能分享更多您所处的环境吗?
0赞 eetaSanglo 11/16/2023
谢谢你,@Nick。外部应用程序传递有效负载(以该形式)。本来希望第二个元素的值是 json 对象,不幸的是它不是,并试图探索是否有优雅的解决方法。
0赞 Nick 11/16/2023
它如何从外部应用程序进入您的 MySQL 代码?
0赞 eetaSanglo 11/17/2023
应用程序使用有效负载调用存储过程(在应用程序中计算它,并将其作为参数传递给存储过程)