首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用pg-promise的多行插入

使用pg-promise的多行插入
EN

Stack Overflow用户
提问于 2016-05-18 21:24:08
回答 2查看 34.1K关注 0票数 46

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

代码语言:javascript
复制
INSERT INTO tmp(col_a,col_b) VALUES('a1','b1'),('a2','b2')...

有没有一种方法可以很容易地做到这一点,最好是对于像这样的对象数组:

代码语言:javascript
复制
[{col_a:'a1',col_b:'b1'},{col_a:'a2',col_b:'b2'}]

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

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

代码语言:javascript
复制
INSERT INTO tmp(col_a,col_b) VALUES(${col_a},${col_b})

作为一个附带问题:使用${}表示法的插入是否可以防止SQL注入?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-18 22:28:06

我是pg-promise的作者。

在该库的较早版本中,Performance Boost文章中的简化示例介绍了这一点,在编写高性能数据库应用程序时,这篇文章仍然是很好的读物。

较新的方法是依赖于helpers namespace,它最终是灵活的,并针对性能进行了优化。

代码语言:javascript
复制
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);

参考接口:ColumnSetinsert

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

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

  • 单行INSERT
  • multi-row INSERT
  • single-row UPDATE
  • multi-row UPDATE

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

注入?

是的,但不是一个人。如果要动态插入模式/表/列名,使用SQL Names是很重要的,它将保护您的代码不受SQL注入的影响。

相关问题:PostgreSQL multi-row updates in Node.js

额外服务

Q:如何同时获取每条新记录的 id

A:只需将RETURNING id附加到查询并使用many方法执行它,即可执行

代码语言:javascript
复制
const query = pgp.helpers.insert(values, cs) + ' RETURNING id';
    
const res = await db.many(query);
//=> [{id: 1}, {id: 2}, ...]

或者更好的方法是,获取id-s,并使用map方法将结果转换为整数数组

代码语言:javascript
复制
const res = await db.map(query, undefined, a => +a.id);
//=> [1, 2, ...]

要了解我们在那里使用+的原因,请参阅:pg-promise returns integers as strings

更新-1

要插入大量记录,请参阅Data Imports

更新-2

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

代码语言:javascript
复制
// 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);
票数 111
EN

Stack Overflow用户

发布于 2021-07-31 16:22:25

试试https://github.com/datalanche/node-pg-format -例如

代码语言:javascript
复制
var format = require('pg-format');

var myNestedArray = [['a', 1], ['b', 2]];
var sql = format('INSERT INTO t (name, age) VALUES %L', myNestedArray); 
console.log(sql); // INSERT INTO t (name, age) VALUES ('a', '1'), ('b', '2')

与对象数组的工作方式类似。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37300997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档