当前位置: 首页 > 面试题库 >

具有pg-promise的多行插入

井修雅
2023-03-14
问题内容

我想用一个INSERT查询插入多个行,例如:

INSERT INTO tmp(col_a,col_b) VALUES('a1','b1'),('a2','b2')...

有没有一种方法可以轻松地做到这一点,最好是针对这样的对象数组:

[{col_a:'a1',col_b:'b1'},{col_a:'a2',col_b:'b2'}]

我可能最终将500条记录放在一个块中,因此运行多个查询将是不可取的。

到目前为止,我只能对单个对象执行此操作:

INSERT INTO tmp(col_a,col_b) VALUES(${col_a},${col_b})

附带的问题:使用${}符号插入是否可以防止SQL注入?


问题答案:

我是pg-promise的作者。

在旧版本的库中,Performance Boost文章中的简化示例涵盖了这一点,在编写高性能数据库应用程序时,它仍然是一本好书。

更新的方法是依靠helpers名称空间,该名称空间最终是灵活的,并且针对性能进行了优化。

const pgp = require('pg-promise')({
    /* initialization options */
    capSQL: true // capitalize all generated SQL
});
const db = pgp(/*connection*/);

// our set of columns, to be created only once (statically), and then reused,
// to let it cache up its formatting templates for high performance:
const cs = new pgp.helpers.ColumnSet(['col_a', 'col_b'], {table: 'tmp'});

// data input values:
const values = [{col_a: 'a1', col_b: 'b1'}, {col_a: 'a2', col_b: 'b2'}];

// generating a multi-row insert query:
const query = pgp.helpers.insert(values, cs);
//=> INSERT INTO "tmp"("col_a","col_b") VALUES('a1','b1'),('a2','b2')

// executing the query:
await db.none(query);

参见API:ColumnSet,插入。

这样的插入甚至不需要事务,因为如果一组值插入失败,则不会插入任何值。

您可以使用相同的方法来生成以下任何查询:

  • 单排 INSERT
  • 多行 INSERT
  • 单排 UPDATE
  • 多行 UPDATE

使用$ {}表示法插入是否可以防止SQL注入?

是的,但并不孤单。如果要动态插入模式/表/列名称,则使用SQL名称很重要,这将保护您的代码免于SQL注入。

问:如何同时获取id每个新记录?

答: 只需将其追加RETURNING id到查询中,然后使用方法many执行即可:

const query = pgp.helpers.insert(values, cs) + 'RETURNING id';

const res = await db.many(query);
//=> [{id: 1}, {id: 2}, ...]

甚至更好的方法是,获取id-s,然后使用map方法将结果转换为整数数组:

const res = await db.map(query, [], a => +a.id);
//=> [1, 2, ...]

更新1

有关插入大量记录的信息,请参见数据导入。

更新2

使用v8.2.1和更高版本,您可以将静态查询生成包装到一个函数中,以便可以在查询方法中生成静态查询生成,以在查询生成失败时拒绝:

// generating a multi-row insert query inside a function:
const query = () => pgp.helpers.insert(values, cs);
//=> INSERT INTO "tmp"("col_a","col_b") VALUES('a1','b1'),('a2','b2')

// executing the query as a function that generates the query:
await db.none(query);


 类似资料:
  • 我想使用单个查询插入多行,例如: 是否有一种方法可以轻松做到这一点,最好是针对如下对象数组: 我最终可能会在一个块中有500条记录,因此不希望运行多个查询。 到目前为止,我只能为单个对象执行此操作: 顺便问一个问题:使用< code>${}符号的插入是否可以防止SQL注入?

  • 问题内容: 我有一个需要插入多个记录的场景。我有一个表结构,如id(其他表中的fk),key(char),value(char)。需要保存的输入将是上述数据的数组。示例:我有一些数组对象,例如: 在MS SQL中,我将创建并传递TVP。我不知道如何在postgres中实现。所以现在我要做的是使用pg- promise库将列表中的所有项目保存在postgres sql中的单个查询中。我找不到任何文档

  • 问题内容: 我想将超时添加到pg- promise查询,以便如果数据库尚未响应,则在一段时间后它们将失败。有什么建议的方法吗?还是我应该做一个可以处理定时器并拒绝诺言的自定义包装器(如果为时已晚)? 问题答案: 来自pg-promise的作者… pg-promise不支持查询取消,因为它可以解决数据库设计错误或查询执行不正确的问题。 PostgreSQL支持在执行耗时的查询时应使用的事件,因此无需

  • 我在节点js代码中有2个数组 我试着用一个数组来做。它成功地执行了,但它不能与2个数组一起工作。我应该怎么做呢? 我为一个数组编写的Mysql插入查询如下所示:

  • 问题内容: 可以这样插入一行: 这种方法会自动注释掉任何特殊字符。 如何一次插入多行? 我需要实现这一点: 我可以只使用js字符串运算符手动编译此类行,但是随后我需要以某种方式添加特殊字符转义符。 问题答案: 下面这篇文章:性能提升,从PG-承诺库,其建议的方法: 完全按照您的情况使用的示例: 它也将与一系列对象一起工作: 更新1 有关通过单个查询的高性能方法,请参见使用pg-promise进行多

  • 我正在开发基于spring+Hibernate的web应用程序。在这个应用程序中,我必须对数据库中的50000个可用记录进行计算。当前逻辑:- 循环0到50000(所有50000记录彼此独立) 选择第i个元素 对第i个元素执行计算(删除CALCULATION_TEMP表(如果存在),创建新表CALCULATION_TEMP并在CALCULATION_TEMP表中插入计算) 在步骤3表上进行一些计算