如何在Node.js(Express)中实现参数化查询并获取最后插入ID
Node.js + Express:实现参数化查询与获取最后插入ID
一、参数化查询的正确实现
你的原有代码存在SQL注入风险,而且SELECT语句里的genderTypeId='genderTypeId'是硬编码字符串(未引用变量),会导致查询逻辑错误。使用参数化查询可以彻底避免注入问题,同时修正逻辑错误。
mysql2(你用的pool.execute属于mysql2的API)支持两种参数化方式,最常用的是?占位符:
- 把SQL语句中的变量替换成
? - 执行查询时,将参数以数组形式传入
pool.execute的第二个参数,mysql2会自动处理转义和类型匹配
二、获取最后插入ID的正确方式
pool.execute执行插入语句后,返回的结果是一个数组,第一个元素是包含操作信息的对象(其中就有insertId),直接取datass.insertId是错误的,需要先解构出结果对象。
另外,判断记录是否存在时,rows<1的写法不严谨,应该用rows.length === 0(因为rows是查询返回的数组)。
修改后的完整代码
static async addServiceDetail(userId, serviceId, genderTypeId, price, serviceName) { // 参数化查询:检查记录是否已存在 const checkSql = `SELECT id from servicesdetail WHERE userId=? AND serviceId=? AND genderTypeId=?`; const [rows] = await pool.execute(checkSql, [userId, serviceId, genderTypeId]); if (rows.length === 0) { // 参数化插入新记录 const insertSql = `INSERT INTO servicesdetail (userId, serviceId, genderTypeId, price, serviceName) VALUES (?, ?, ?, ?, ?)`; const [insertResult] = await pool.execute(insertSql, [userId, serviceId, genderTypeId, price, serviceName]); console.log('last inserted id is ' + insertResult.insertId); return insertResult.insertId; // 可选:返回ID给调用方 } else { console.log('already exist'); return null; // 可选:返回标识表示记录已存在 } }
额外说明
- 如果偏好命名占位符(比如
:userId),可以在创建连接池时配置namedPlaceholders: true,然后SQL写成WHERE userId=:userId,参数传对象{ userId, serviceId, genderTypeId } pool.execute会预处理SQL语句,比pool.query性能更优,适合重复执行的查询场景- 永远不要直接拼接变量到SQL字符串中,这是SQL注入的高危操作
内容的提问来源于stack exchange,提问作者Diana
相关产品推荐
相关产品推荐

