TypeORM+MySQL报错QueryFailedError: where子句存在未知列NaN如何解决?
错误根源
你的报错核心是Number(user_id)转换后得到了NaN,拼接到SQL语句后生成了WHERE a.user_id = NaN的逻辑,MySQL会将未加引号的NaN识别为列名,因此抛出「where子句中存在未知列'NaN'」的错误。
而原始TypeORM写法触发错误的原因大概率是:你使用的TypeORM版本对多层嵌套关联的where查询支持存在兼容问题,或传入的user_id本身就是非法值。
排查步骤
- 检查接口参数解析逻辑:Express路由中获取的路径参数/查询参数默认是字符串类型,你需要手动将其转为数字后再传入Service,否则即使TypeScript声明为
number类型,运行时依然是字符串值,若传入的是非数字字符串,转换后就会得到NaN - 校验
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
相关产品推荐
相关产品推荐

