You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang使用sqlx写入MySQL JSON字段数组被转义为字符串如何解决

问题场景

需要向MySQL中插入JSON对象,原始实现代码如下:

array := []string{"BT", "TL", "CN"}
s, err := json.Marshal(array)
if err != nil {
    return err
}
_, err := db.Exec("update setting set multilingual = json_set(multilingual, '$.supported', ?) where id = ?", s, 10)
if err != nil {
    return err
}

预期数据库中multilingual字段的存储结果为:

{"supported": ["BT","TL","CN"]}

实际写入后得到的结果为:

{"supported": "[\"BT\",\"TL\",\"CN\"]"}

运行环境为使用sqlx作为Golang连接MySQL的依赖库,需要修复该写入异常问题。

问题原因

Go中json.Marshal序列化切片得到的是JSON格式的字节序列,直接将该值作为参数传入JSON_SET函数时,MySQL会将其判定为普通字符串类型,而非JSON结构值,因此存储时会自动对字符串中的引号做转义,最终将路径下的值存为转义后的字符串,而非预期的JSON数组。

修复方法

修改SQL语句,对传入的序列化JSON参数做显式类型转换,告知MySQL将该值作为JSON类型解析,只需要给参数包裹CAST(? AS JSON)即可,修正后的代码如下:

array := []string{"BT", "TL", "CN"}
s, err := json.Marshal(array)
if err != nil {
    return err
}
// 显式将传入参数转换为JSON类型,避免被识别为普通字符串
_, err := db.Exec("update setting set multilingual = json_set(multilingual, '$.supported', CAST(? AS JSON)) where id = ?", s, 10)
if err != nil {
    return err
}

执行上述代码后,写入结果就会和预期一致,$.supported路径下存储的是原生JSON数组,不会出现额外的转义字符。

该方案无需调整Go侧序列化逻辑,也不需要更换数据库驱动,仅修改SQL语句即可生效,兼容原生database/sql、sqlx等所有常用Go MySQL连接库。

内容的提问来源于stack exchange,提问作者Tony Cheng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 02:21:22