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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:55:24