从select中插入Knex.js

时间:2015-04-25 21:02:42

标签: javascript node.js knex.js

我正在尝试通过Knex.js生成类似以下的查询:

INSERT INTO table` ("column1", "column2")
SELECT "someVal", 12345)
WHERE NOT EXISTS (
    SELECT 1
    FROM table
    WHERE "column2" = 12345
)

基本上,我只想在特定值尚不存在时才插入值。但Knex.js似乎不知道如何做到这一点;如果我调用knex.insert()(没有值),它会生成“插入默认值”查询。

我尝试了以下内容:

pg.insert()
                .into(tableName)
                .select(_.values(data))
                .whereNotExists(
                    pg.select(1)
                        .from(tableName)
                        .where(blah)
                );

但这仍然只是给了我默认值的东西。我尝试添加.columns(Object.keys(data)),希望insert()能够尊重这一点,但没有运气。

是否可以使用knex生成我想要的查询,还是只需要构建原始查询,而不使用Knex.js方法?

2 个答案:

答案 0 :(得分:4)

我认为需要将select传递给insert:

pg.insert(knex.select().from("tableNameToSelectDataFrom")).into("tableToInsertInto");

另外,为了选择常量值或表达式,您需要在select中使用knex.raw表达式:

knex.select(knex.raw("'someVal',12345")).from("tableName")

这是我的第一篇文章,我没有测试你的具体例子,但我做了类似的事情,就像你使用上述技术所要求的那样。

答案 1 :(得分:0)

我找到的最全面的答案(INSERT 的显式列名和 SELECT 语句中的自定义值)在这里:

https://github.com/knex/knex/issues/1056#issuecomment-156535234

by Chris Broome

这是该解决方案的副本:

const query = knex.from(knex.raw('?? (??, ??)', ['orders', 'user_id', 'email']))
  .insert(function() {
    this.from('users AS u')
      .where('u.username', 'jdoe')
      .select('user_id', knex.raw('? AS ??', ['jdoe@gmail.com', 'email']))
   });
console.log(qb.toString());

和 SQL 输出:

insert into "orders" ("user_id", "email")
select "user_id", 'jdoe@gmail.com' AS "email"
  from "users" as "u"
 where "u"."username" = 'jdoe'

另一种方法(由 Knex 开发人员提供):https://github.com/knex/knex/commit/e74f43cfe57ab27b02250948f8706d16c5d821b8#diff-cb48f4af7c014ca6a7a2008c9d280573R608 - 也使用 knex.raw