我是pg-promise的作者。
在旧版本的库中,性能提升文章中的简化示例涵盖了这一点,在编写高性能数据库应用程序时,这仍然是一个很好的阅读。
较新的方法是依赖于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
- 多行
INSERT
- 单排
UPDATE
- 多行
UPDATE
使用 ${} 符号的插入是否可以防止 sql 注入?
是的,但并不孤单。如果您要动态插入模式/表/列名称,请务必使用SQL Names,这将保护您的代码免受 SQL 注入。
相关问题:Node.js 中的 PostgreSQL 多行更新
问:如何同时获取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, undefined, a => +a.id);
//=> [1, 2, ...]
要了解我们为什么在那里使用+
,请参阅:pg-promise 将整数作为字符串返回。
更新-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);