我有一个需要插入多条记录的场景。我有一个表结构,如 id(它是来自其他表的 fk)、key(char)、value(char)。需要保存的输入将是上述数据的数组。例子: 我有一些数组对象,例如:
lst = [];
obj = {};
obj.id= 123;
obj.key = 'somekey';
obj.value = '1234';
lst.push(obj);
obj = {};
obj.id= 123;
obj.key = 'somekey1';
obj.value = '12345';
lst.push(obj);
在 MS SQL 中,我会创建 TVP 并通过它。我不知道如何在 postgres 中实现。 所以现在我想做的是使用 pg-promise 库将列表中的所有项目保存在 postgres sql 的单个查询中。我无法从文档中找到任何文档/理解。任何帮助表示赞赏。谢谢。
最佳答案
我是 pg-promise 的作者.
有两种方法可以插入多条记录。第一种也是最典型的方式是通过事务来确保所有记录都被正确插入,或者一个都不插入。
与 pg-promise它是通过以下方式完成的:
db.tx(t => {
const queries = lst.map(l => {
return t.none('INSERT INTO table(id, key, value) VALUES(${id}, ${key}, ${value})', l);
});
return t.batch(queries);
})
.then(data => {
// SUCCESS
// data = array of null-s
})
.catch(error => {
// ERROR
});
您使用方法 tx 发起交易,然后创建所有 INSERT
查询 promise ,然后将它们全部解析为 batch .
第二种方法是将所有插入值连接到单个 INSERT
查询中,我在 Performance Boost 中对此进行了详细说明.另见:Multi-row insert with pg-promise .
更多示例参见 Tasks和 Transactions .
加法
值得指出的是,在大多数情况下,我们不会插入记录id
,而是让它自动生成。有时我们想取回新的 id-s,而在其他情况下我们不在乎。
上面的示例使用 null
-s 数组解析,因为 batch用一组单独的结果和方法解析 none根据其 API,使用 null
解析。
假设我们想要生成新的 id-s,并且想要将它们全部取回。为此,我们将代码更改为以下内容:
db.tx(t => {
const queries = lst.map(l => {
return t.one('INSERT INTO table(key, value) VALUES(${key}, ${value}) RETURNING id',
l, a => +a.id);
});
return t.batch(queries);
})
.then(data => {
// SUCCESS
// data = array of new id-s;
})
.catch(error => {
// ERROR
});
即变化是:
- 我们不插入
id
值 - 我们替换方法none与 one , 从每个插入中获取一行/对象
- 我们将
RETURNING id
附加到查询中以获取值 - 我们添加
a => +a.id
来进行自动行转换。另见 pg-promise returns integers as strings了解+
的用途。
UPDATE-1
有关通过单个 INSERT
查询的高性能方法,请参阅 Multi-row insert with pg-promise .
UPDATE-2
必读文章:Data Imports .
关于node.js - 使用 pg-promise 插入多条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36233566/