Node.js执行MySQL WHERE IN查询仅返回部分记录的原因及解决方法
问题成因
- 预处理语句传参逻辑错误:你从请求query中拿到的
portfolioid_list是完整字符串"69,70,71",而非数值数组。使用mysql2的execute预处理方法时,给IN(?)占位符传入该字符串,会被识别为单个字符串值转义,最终执行的SQL等价于WHERE idseller_portfolio_item IN ('69,70,71')。 - 数据库隐式类型转换:数值字段
idseller_portfolio_item和字符串'69,70,71'比较时,MySQL会自动将字符串转换为数值,逗号后的内容会被截断,最终仅得到数值69,因此只返回第一个ID匹配的结果。你直接在数据库执行的SQL是IN(69,70,71)三个独立数值,所以结果正常。 - 额外的参数校验bug:你在
if判断中访问了未声明的portfolioid_list变量,该变量是在else块中用const声明的块级作用域变量,if分支访问会抛出引用错误,参数校验逻辑完全失效。
修复方案
首先修正参数校验逻辑,再将字符串拆分为合法数值数组,最后根据数组长度生成对应数量的预处理占位符即可,修复后代码如下:
const mysql = require('mysql2'); const errorCodes = require('source/error-codes'); const PropertiesReader = require('properties-reader'); const prop = PropertiesReader('properties.properties'); const con = mysql.createConnection({ host: prop.get('server.host'), user: prop.get("server.username"), password: prop.get("server.password"), port: prop.get("server.port"), database: prop.get("server.dbname") }); exports.getSellerPortfolioItemImagesByPortfolioList = (event, context, callback) => { context.callbackWaitsForEmptyEventLoop = false; const params = event.queryStringParameters; // 先提前获取参数,修复校验逻辑 const portfolioIdStr = params?.portfolioid_list; if (!portfolioIdStr) { const response = errorCodes.missing_parameters; return callback(null, response) } // 拆分字符串为数值数组,过滤非法值 const idArray = portfolioIdStr.split(',') .map(id => parseInt(id.trim(), 10)) .filter(id => !isNaN(id)); if (idArray.length === 0) { const response = errorCodes.missing_parameters; return callback(null, response) } // 生成和数组长度匹配的占位符 const placeholders = idArray.map(() => '?').join(','); const sql = `SELECT * FROM peresia.seller_portfolio_item_images WHERE idseller_portfolio_item IN (${placeholders})`; con.execute(sql, idArray, function (err, result) { if (err) { console.log(err); const response = errorCodes.internal_server_error; return callback(null, response); } const response = { "statusCode": 200, "headers": { "Content-Type": "application/json" }, "body": JSON.stringify(result), "isBase64Encoded": false }; callback(null, response) }); };
内容的提问来源于stack exchange,提问作者PeakGen
相关产品推荐
相关产品推荐

