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

如何使用JSON_REPLACE和JSON_ARRAY修改MySQL JSON字段的数组类型键值

解决方案

最优方案:JSON序列化+参数化查询(推荐)

这个方案适配所有数组长度,同时规避SQL注入风险,是最稳妥的实现方式:

const religionPreferences = ["Buddhism","Christianity","Non religious"]
// 先将JS数组序列化为标准JSON字符串
const religionsJson = JSON.stringify(religionPreferences)
// 使用参数化查询传入参数,不要直接拼接变量到SQL语句中
// 以下为node-mysql2驱动的写法,其他驱动参数化语法可对应调整
const [updateResult] = await connection.execute(
  `UPDATE users 
   SET preferences = JSON_REPLACE(preferences, '$.religions', CAST(? AS JSON)) 
   WHERE id = ? 
   LIMIT 1`,
  [religionsJson, req.params.id]
)

原理说明:JSON.stringify输出的是标准JSON数组格式,通过CAST(? AS JSON)显式转为MySQL的JSON类型后存入字段,不会被识别为普通字符串,0-14个元素的场景都可以直接适配。

备选方案:动态拼接JSON_ARRAY参数

如果特殊场景不能用参数化查询,可以动态生成JSON_ARRAY的入参:

const religionPreferences = ["Buddhism","Christianity","Non religious"]
// 对每个数组元素做SQL转义,避免注入风险,示例用node-mysql2的escape方法
const escapedItems = religionPreferences.map(item => connection.escape(item))
// 动态拼接JSON_ARRAY的参数列表
const jsonArrayPart = `JSON_ARRAY(${escapedItems.join(',')})`
// 拼接完整SQL
const sql = `UPDATE users 
SET preferences = JSON_REPLACE(preferences, '$.religions', ${jsonArrayPart})
WHERE id = ${connection.escape(req.params.id)} 
LIMIT 1`

原理说明:动态根据数组长度生成对应数量的转义后参数传入JSON_ARRAY,即使是空数组也会生成JSON_ARRAY()的合法语法。

原写法报错原因

直接把JS数组插入模板字符串时,JS会自动调用数组的toString()方法,将["a","b"]转换为a,b的格式,SQL无法识别该格式为数组,因此会出现语法错误或者存入非预期的字符串格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 21:45:00