【问题标题】:Select from an existing query in knex.js从 knex.js 中的现有查询中选择
【发布时间】:2017-02-08 15:00:20
【问题描述】:

在给定现有子查询的情况下,我正在使用knex.js 构建查询。跟随this的答案,以及GitHub中的this线程,我尝试了以下方法:

const knex = require("knex")({client: 'pg'});

const subQuery = knex.queryBuilder().select(1);

const query = knex.queryBuilder().select('*').from(subQuery);

console.log(query.toString());

但结果是:

select * from select 1

这显然有语法错误。我的预期结果是:

select * from (select 1)

为什么不加括号,怎么改?

【问题讨论】:

    标签: javascript node.js knex.js


    【解决方案1】:

    您的方式,您的做法似乎是正确的,我想说这是knex 中的错误,为什么它不起作用(我是knex 的合作者)。

    无论如何,有几种方法可以做到这一点......

    const knex = require("knex")({client: 'pg'});
    
    const subQuery = knex.select(1).as('t1');
    const query = knex.select('*').from(subQuery);
    console.log(query.toSQL());
    
    { method: 'select',
      options: {},
      timeout: false,
      cancelOnTimeout: false,
      bindings: [],
      __knexQueryUid: '69d240ad-f5f8-4bc4-8c1d-fb9432af1da2',
      sql: 'select * from (select 1) as "t1"' }
    

    或者您可以使用带有function() 子查询的旧样式,它不需要.as(),但支持它...

    const query = knex.select('*').from(sq => sq.select(1));
    console.log(query.toSQL());
    
    { method: 'select',
      options: {},
      timeout: false,
      cancelOnTimeout: false,
      bindings: [],
      __knexQueryUid: '31beb080-c89a-43b2-b112-546077330e82',
      sql: 'select * from (select 1)' }
    

    【讨论】:

    • 我使用了第一个解决方案,as('t1') 就像一个魅力。谢谢。
    • 大大简化了我的代码。非常感谢你。你是救命稻草!
    【解决方案2】:

    我发现一个丑陋(但有效)的解决方案是使用 knex.rawsubQuery.toString

    const query = knex.queryBuilder()
        .select('*')
        .from(knex.raw(`(${subQuery})`);
    

    我不认为这是最好的答案,而且我确定我遗漏了什么,所以我还不接受这个答案。

    【讨论】:

    • 您永远不应该使用.toString() 来传递原始查询...这将导致 knex 进行插值,例如参数绑定本身,它将无法使用数据库驱动程序的实现来防止 SQL 注入。 .toSQL() 分别为您提供绑定和 sql。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 2019-04-04
    • 1970-01-01
    相关资源
    最近更新 更多