如何运行Knex toNative()返回的查询语句?
问题
Knex的toNative()方法返回的原生查询结构如下:
{ sql: 'select "firstName", "lastName" from "table1" where ((("age" >= $1 and "country" = $2) or ("age" < $3)))', bindings: [25, 'NL', 25] }
尝试用knex.raw(q.sql, q.bindings)运行该查询时,报错:
Expected 3 bindings, saw 0
平时用raw查询都是用?作为占位符,替换成?后能运行但不够优雅,请问怎么直接运行toNative()返回的原生查询?
解决方法
直接调用Knex底层数据库客户端的查询方法即可,不需要通过knex.raw中转:
// 先获取toNative()返回的查询结构 const nativeQuery = knex('table1') .select('firstName', 'lastName') .where(builder => { builder.where('age', '>=', 25) .where('country', 'NL') .orWhere('age', '<', 25); }) .toNative(); // 用Knex的数据库客户端直接执行原生查询 knex.client.query(nativeQuery.sql, nativeQuery.bindings) .then(result => { // 处理查询结果,不同数据库驱动的结果格式略有差异 console.log('查询结果:', result.rows); }) .catch(err => { console.error('查询出错:', err); });
原因说明
knex.raw()会重新解析传入的SQL,默认识别?作为占位符,再根据数据库类型转换为对应的原生占位符(比如PostgreSQL的$1)。但你传入的是已经生成好的带原生占位符的SQL,Knex找不到它预期的?占位符,因此报错“缺少绑定参数”。
直接调用knex.client.query()则跳过了Knex的SQL解析步骤,直接把原生SQL和绑定参数传给数据库驱动执行,完全匹配toNative()的输出格式。
内容的提问来源于stack exchange,提问作者CharlesS
相关产品推荐
相关产品推荐

