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

TypeORM+MySQL报错QueryFailedError: where子句存在未知列NaN如何解决?

错误根源

你的报错核心是Number(user_id)转换后得到了NaN,拼接到SQL语句后生成了WHERE a.user_id = NaN的逻辑,MySQL会将未加引号的NaN识别为列名,因此抛出「where子句中存在未知列'NaN'」的错误。
而原始TypeORM写法触发错误的原因大概率是:你使用的TypeORM版本对多层嵌套关联的where查询支持存在兼容问题,或传入的user_id本身就是非法值。

排查步骤

  1. 检查接口参数解析逻辑:Express路由中获取的路径参数/查询参数默认是字符串类型,你需要手动将其转为数字后再传入Service,否则即使TypeScript声明为number类型,运行时依然是字符串值,若传入的是非数字字符串,转换后就会得到NaN
  2. 校验user.id的合法性:确认usersRepository.findById返回的用户对象中id字段是合法正整数,没有被序列化规则排除

修复方案

1. 修复Repository查询逻辑

不要手动拼接SQL(存在SQL注入风险),直接使用Appointment表的外键字段user_id查询即可,同时提前做参数合法性校验:

public async findByUserId(user_id: number): Promise<Appointment[]> {
  // 提前校验参数合法性,避免非法值传入
  if (isNaN(user_id) || !Number.isInteger(user_id) || user_id <= 0) {
    return [];
  }
  return this.ormRepository.find({
    relations: ['user', 'schedule', 'schedule.experience'],
    where: {
      // 直接使用表中存在的外键字段查询,不需要嵌套关联对象
      user_id: user_id
    }
  });
}

2. 入参校验补充

在Service层或接口DTO层增加参数校验规则,确保传入的用户ID是合法正整数,避免非法值进入查询逻辑。

3. 如确实需要使用原生SQL

请使用参数化查询,不要直接拼接字符串:

const appointments = await this.ormRepository.query(
  `SELECT * FROM Appointment a 
  LEFT JOIN \`User\` u ON u.id  = a.user_id 
  LEFT JOIN Schedule s ON s.id = a.schedule_id 
  LEFT JOIN Experience e ON e.id = s.exp_id 
  WHERE a.user_id = ?`,
  [user_id]
);

内容的提问来源于stack exchange,提问作者Vinícius Da Silva Sousa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 13:00:00