Knex生成错误查询:JOIN条件用反引号而非单引号问题
Knex JOIN条件中字符串值被反引号包裹而非单引号的问题解决
你遇到的问题是Knex在生成JOIN的ON条件时,错误地将字符串值用反引号(`)包裹,而不是单引号('),这会导致数据库把这些值识别为表/字段名而非字符串常量,进而查询失败。
问题原因
Knex的.andOn({列名: 值})这种对象语法,在处理JOIN的ON条件时,对值的类型判断逻辑和.where()不同:当值是空字符串、或者变量被Knex误判为标识符时,它会把值当作表/字段名处理,用反引号包裹。而.where()的对象语法则不会出现这个问题,因为where子句的处理逻辑更倾向于识别值类型。
解决方案
推荐用以下两种方式修复:
1. 使用.andOn()的三参数明确语法
把对象形式的条件改成(列名, 操作符, 值)的三参数写法,Knex会明确识别右边的参数是值,自动用单引号包裹:
const query = knex .select('ue.username', 'ue.permission', 'ue.status') .from('user_entity as ue') .join('device_entity as de', function () { this .on('de.username', '=', 'ue.username') .andOn('de.deleted', '=', '') // 三参数写法 .andOn('de.token', '=', token) .andOn('de.uid', '=', uid); }) .where({'ue.deleted': ''})
2. 用knex.raw()强制指定值类型
如果坚持用对象语法,可以用knex.raw()包裹值,强制Knex将其视为字符串常量:
const query = knex .select('ue.username', 'ue.permission', 'ue.status') .from('user_entity as ue') .join('device_entity as de', function () { this .on('de.username', '=', 'ue.username') .andOn({'de.deleted': knex.raw('?', [''])}) .andOn({'de.token': knex.raw('?', [token])}) .andOn({'de.uid': knex.raw('?', [uid])}); }) .where({'ue.deleted': ''})
另外,还要确认token和uid变量确实是字符串类型,如果它们被意外转成了对象或其他非字符串类型,Knex也会误判为标识符。
修改后生成的SQL会符合你的预期,字符串值会用单引号包裹,查询可以正常执行。
内容的提问来源于stack exchange,提问作者Júnior Nascimento
相关产品推荐
相关产品推荐

