MySQL更新存放JSON的字段、\“ 转义成 “的问题描述

吾爱主题 阅读:182 2022-12-22 16:42:00 评论:0

本篇介绍在执行MySQL线上变更时遇到的问题,表现为"更新JSON字段时,实际更新的值与SQL语句中的值不一致,JSON格式错误",如下;

问题描述

处理线上问题,需要新插入一条记录;将原JSON粘贴出来,修改部分字段,然后提交SQL更新语句,原始JSON如下:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 {      "playerQualifyType" : 1 ,      "surveyId" : 14 ,      "playerRegisterEndTime" : 1670860799000 ,      "planName" : "《碧蓝大陆》先锋测试招募!" ,      "planStatus" : 2 ,      "playerRegisterStartTime" : 1669860000000 ,      "gameName" : "碧蓝大陆" ,      "developerName" : "海南羽弘信息技术有限公司" ,      "planStartTime" : 1673316000000 ,      "qualificationCodeUrl" : "" ,      "updateTime" : 1669777099000 ,      "planPlayerNum" : 1500 ,      "extend" : "{\"innerDesc\":\"\",\"planId\":16,\"verifyOperator\":\"Akira-11126666\",\"verifyResultDesc\":\"\",\"verifyResultDescImgList\":[],\"verifyResultStatus\":2,\"verifyTime\":1669777099887}" ,      "planEndTime" : 1673884800000 ,      "pkgStatus" : 0 }

现提交SQL变更单,执行SQL语句如下:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 update t set `json_field` = ' {      "playerQualifyType": 1,      "surveyId": 14,      "playerRegisterEndTime": 1670860799000,      "planName": "《碧蓝大陆》先锋测试招募!",      "planStatus": 2,      "playerRegisterStartTime": 1669860000000,      "gameName": "碧蓝大陆",      "developerName": "海南羽弘信息技术有限公司",      "planStartTime": 1673316000000,      "qualificationCodeUrl": "",      "updateTime": 1669777099000,      "planPlayerNum": 1500,      "extend": "{\"innerDesc\":\"\",\"planId\":16,\"verifyOperator\":\"Akira-11126666\",\"verifyResultDesc\":\"\",\"verifyResultDescImgList\":[],\"verifyResultStatus\":2,\"verifyTime\":1669777099887}",      "planEndTime": 1673884800000,      "pkgStatus": 0 } ' where id = 55;

结果数据库中更新后查出来的纪录如下,不满足JSON格式了,仔细检查发现是extend字段的值中的反斜杠全部没有了,JSON解析失败

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 {      "playerQualifyType" : 1 ,      "surveyId" : 14 ,      "playerRegisterEndTime" : 1670860799000 ,      "planName" : "《碧蓝大陆》先锋测试招募!" ,      "planStatus" : 2 ,      "playerRegisterStartTime" : 1669860000000 ,      "gameName" : "碧蓝大陆" ,      "developerName" : "海南羽弘信息技术有限公司" ,      "planStartTime" : 1673316000000 ,      "qualificationCodeUrl" : "" ,      "updateTime" : 1669777099000 ,      "planPlayerNum" : 1500 ,      "extend" : "{" innerDesc ":" "," planId ":16," verifyOperator ":" Akira -11126666 "," verifyResultDesc ":" "," verifyResultDescImgList ":[]," verifyResultStatus ":2," verifyTime ":1669777099887}" ,      "planEndTime" : 1673884800000 ,      "pkgStatus" : 0 }

问题排查

联系DBA描述问题,得到的回复是——

\"相当于就转义成 "了,这是MySQL自身处理的结果;

实验如下:

而代码中执行的就没问题,原因是代码中该字段对应的Java类型为String,也就是说原JSON的外层因为套了一层双引号"",因此还会有一次转义符的嵌套,如下;

?
1 \"extend\":\"{\\\"innerDesc\\\":\\\"\\\",\\\"planId\\\":16,\\\"verifyOperator\\\":\\\"Akira-11126666\\\",\\\"verifyResultDesc\\\":\\\"\\\",\\\"verifyResultDescImgList\\\":[],\\\"verifyResultStatus\\\":2,\\\"verifyTime\\\":1669777099887}\"

因此,代码中执行JSON字符串的MySQL插入,实际入库的值与预期一致;正确的SQL如下:

?
1 2 3 4 5 update t set `json_field` = ' {\"playerQualifyType\":1,\"surveyId\":14,\"playerRegisterEndTime\":1670860799000,\"planName\":\"《碧蓝大陆》先锋测试招募!\",\"planStatus\":2,\"playerRegisterStartTime\":1669860000000,\"gameName\":\"碧蓝大陆\",\"developerName\":\"海南羽弘信息技术有限公司\",\"planStartTime\":1673316000000,\"qualificationCodeUrl\":\"\",\"updateTime\":1669777099000,\"planPlayerNum\":1500,\"extend\":\"{\\\"innerDesc\\\":\\\"\\\",\\\"planId\\\":16,\\\"verifyOperator\\\":\\\"Akira-11126666\\\",\\\"verifyResultDesc\\\":\\\"\\\",\\\"verifyResultDescImgList\\\":[],\\\"verifyResultStatus\\\":2,\\\"verifyTime\\\":1669777099887}\",\"planEndTime\":1673884800000,\"pkgStatus\":0} ' where id = 55;

解决方案

在更新Mysql表的JSON字符串字段时,步骤应该如下:

1. 输入查询语句,找到目标记录,复制JSON字段的值到JSON编辑工具中修改JSON中的属性值

2. 将修改后的JSON粘贴到IDE中,IDE用双引号接收这一串JSON;

3. 执行SQL时,SQL语句中的值以IDE中被双引号包裹的字符串值为SQL中的新的value;

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // 将JSON粘贴进来 整体作为SQL更新语句中的新的value 这里也可以不格式化JSON String formatValue = "{\n" +          "    \"playerQualifyType\": 1,\n" +          "    \"surveyId\": 14,\n" +          "    \"playerRegisterEndTime\": 1670860799000,\n" +          "    \"planName\": \"《碧蓝大陆》先锋测试招募!\",\n" +          "    \"planStatus\": 2,\n" +          "    \"playerRegisterStartTime\": 1669860000000,\n" +          "    \"gameName\": \"碧蓝大陆\",\n" +          "    \"developerName\": \"海南羽弘信息技术有限公司\",\n" +          "    \"planStartTime\": 1673316000000,\n" +          "    \"qualificationCodeUrl\": \"\",\n" +          "    \"updateTime\": 1669777099000,\n" +          "    \"planPlayerNum\": 1500,\n" +          "    \"extend\": \"{\\\"innerDesc\\\":\\\"\\\",\\\"planId\\\":16,\\\"verifyOperator\\\":\\\"Akira-11126666\\\",\\\"verifyResultDesc\\\":\\\"\\\",\\\"verifyResultDescImgList\\\":[],\\\"verifyResultStatus\\\":2,\\\"verifyTime\\\":1669777099887}\",\n" +          "    \"planEndTime\": 1673884800000,\n" +          "    \"pkgStatus\": 0\n" +          "}" ;   // 未格式化 会少去/n换行符 String value = "{\"playerQualifyType\":1,\"surveyId\":14,\"playerRegisterEndTime\":1670860799000,\"planName\":\"《碧蓝大陆》先锋测试招募!\",\"planStatus\":2,\"playerRegisterStartTime\":1669860000000,\"gameName\":\"碧蓝大陆\",\"developerName\":\"海南羽弘信息技术有限公司\",\"planStartTime\":1673316000000,\"qualificationCodeUrl\":\"\",\"updateTime\":1669777099000,\"planPlayerNum\":1500,\"extend\":\"{\\\"innerDesc\\\":\\\"\\\",\\\"planId\\\":16,\\\"verifyOperator\\\":\\\"Akira-11126666\\\",\\\"verifyResultDesc\\\":\\\"\\\",\\\"verifyResultDescImgList\\\":[],\\\"verifyResultStatus\\\":2,\\\"verifyTime\\\":1669777099887}\",\"planEndTime\":1673884800000,\"pkgStatus\":0}" ;

到此这篇关于MySQL更新存放JSON的字段、\“ 转义成 “的文章就介绍到这了,更多相关MySQL JSON转义内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/minghao0508/article/details/128372093

可以去百度分享获取分享代码输入这里。
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

【腾讯云】云服务器产品特惠热卖中
搜索
标签列表
    关注我们

    了解等多精彩内容