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

Node.js登录验证后更新MySQL登录计数报ER_PARSE_ERROR错误

问题原因

你遇到的报错和逻辑问题来自3个核心错误:

  • SQL语法错误:UPDATE 语句不需要搭配 INTO 关键字,INTO是INSERT写入语句的专属语法,这就是抛出ER_PARSE_ERROR的直接原因
  • 缺失WHERE限定条件:你写的更新语句没有指定要更新哪个用户,执行后会把users表所有用户的登录次数字段都改掉,属于严重逻辑漏洞
  • 执行时序问题:更新操作是异步回调,你没等更新执行完成就直接返回登录成功响应,极端场景下会出现页面跳转到首页时登录次数还没更新的情况;另外并发场景下先查值再加1的写法会出现计数不准的问题。
推荐实现方案(原子自增,无并发问题)

不需要提前查询用户历史登录次数,直接通过SQL内置的自增逻辑完成计数更新,性能更好,也不会出现并发计数错误,核心更新语句如下:

UPDATE users SET userLoginCount = userLoginCount + 1 WHERE id = ?

这个语句会自动找到对应用户,把登录次数在原有值基础上加1,不需要在Node.js层做数值计算。

修正后的完整代码
const login = async(req, res) => {
  const { username, password } = req.body;
  if (!username || !password) {
    return res.json({
      status: 'error',
      error: 'Please enter your username and password'
    })
  }

  db.query('SELECT * FROM users WHERE username = ?', [username], async(Err, result) => {
    if (Err) throw Err;
    if (!result.length || !await bcrypt.compare(password, result[0].password)) {
      return res.json({
        status: 'error',
        error: 'Incorrect Username or password'
      })
    }

    const token = jwt.sign(
      { id: result[0].id },
      process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_EXPIRES }
    )
    // 注意:express的cookie配置过期字段是expires,不是expiresIn,原代码这里配置不生效
    const cookieOption = {
      expires: new Date(Date.now() + process.env.COOKIE_EXPIRES * 24 * 60 * 60 * 1000),
      httpOnly: true
    }
    res.cookie('userRegistered', token, cookieOption)

    // 执行登录次数更新,加WHERE条件限定当前登录用户
    db.query(
      'UPDATE users SET userLoginCount = userLoginCount + 1 WHERE id = ?',
      [result[0].id],
      (error, results) => {
        if (error) throw error;
        console.log(results)
        console.log('user ' + username + ' logged in')
        // 等更新完成后再返回成功响应,避免时序问题
        return res.json({
          status: 'success',
          success: 'User has been logged In'
        })
      }
    )
  })
}
补充说明

如果你坚持要沿用「先查历史值→Node.js层加1→更新回表」的思路,也要注意必须加WHERE条件,对应更新语句写法如下,但非常不推荐高并发场景用这种写法:

// 不推荐,并发下会出现计数不准
db.query(
  'UPDATE users SET userLoginCount = ? WHERE id = ?',
  [result[0].userLoginCount + 1, result[0].id],
  (error, results) => {
    // 回调逻辑
  }
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 06:27:24