MySQL多行更新报错:ER_PARSE_ERROR语法错误求助
MySQL多行更新语法错误排查与正确实现
核心问题分析
你的报错有两个关键原因:
- 参数格式错误:
execute方法处理多语句查询时,参数需要是一维数组,按SQL语句中占位符的顺序依次排列,而非嵌套数组。 - JSON对象未序列化:直接传递JavaScript对象给MySQL的JSON字段,会被默认转为
[object Object]字符串,导致语法错误,必须先序列化为标准JSON字符串。
解决方案1:修正多语句的参数传递格式
先将JSON对象序列化为字符串,再把所有参数整理成一维数组:
const query = 'UPDATE `ROW_INFO` SET `JSON` = ? WHERE `ID` = ?;UPDATE `ROW_INFO` SET `JSON` = ? WHERE `ID` = ?;' // 序列化JSON对象,整理为一维参数数组 const values = [ JSON.stringify({foo:'bar1'}), 1, JSON.stringify({foo:'bar2'}), 2 ] await connection.execute(query, values)
解决方案2:更高效的单语句批量更新(推荐)
多语句模式存在SQL注入风险(即便开启multipleStatements也需谨慎),更推荐用单语句实现批量更新,性能更优。可以采用两种写法:
写法一:CASE WHEN语法
const updates = [ { id: 1, json: {foo:'bar1'} }, { id: 2, json: {foo:'bar2'} } ] // 构建CASE WHEN子句 const caseClauses = updates.map(item => `WHEN ${item.id} THEN ?`).join(' ') const values = updates.flatMap(item => [JSON.stringify(item.json), item.id]) const ids = updates.map(item => '?').join(',') const query = ` UPDATE \`ROW_INFO\` SET \`JSON\` = CASE \`ID\` ${caseClauses} END WHERE \`ID\` IN (${ids}) ` await connection.execute(query, [...values, ...updates.map(item => item.id)])
写法二:INSERT ON DUPLICATE KEY UPDATE(需ID为唯一索引/主键)
const updates = [ { id: 1, json: {foo:'bar1'} }, { id: 2, json: {foo:'bar2'} } ] const placeholders = updates.map(() => '(?, ?)').join(',') const values = updates.flatMap(item => [item.id, JSON.stringify(item.json)]) const query = ` INSERT INTO \`ROW_INFO\` (\`ID\`, \`JSON\`) VALUES ${placeholders} ON DUPLICATE KEY UPDATE \`JSON\` = VALUES(\`JSON\`) ` await connection.execute(query, values)
关键注意事项
- 必须用
JSON.stringify()将JavaScript对象转为标准JSON字符串后,再传给MySQL的JSON字段。 - 开启
multipleStatements后要严格校验所有输入,避免SQL注入风险,优先选择单语句批量更新方案。
内容的提问来源于stack exchange,提问作者Alberto Acuña
相关产品推荐
相关产品推荐

