我有一个场景,我需要插入多个记录.我有一个表格结构,如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 => {
- var 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查询承诺,然后将其全部解析为batch.
第二种方法是将所有插入值连接到单个INSERT查询中,我在Performance Boost中详细解释.另请参阅:Multi-row insert with pg-promise.
有关更多示例,请参阅Tasks和Transactions.
加成
值得指出的是,在大多数情况下,我们不会插入记录ID,而是自动生成记录.有时我们希望得到新的id,而在其他情况下我们不在乎.
上面的示例使用null-s的数组解析,因为batch使用单个结果的数组进行解析,方法none根据其API解析为null.
假设我们要生成新的id,我们想让它们全部回来.为了完成这个,我们将把代码改成如下:
- db.tx(t => {
- var 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值
>我们用one替换方法none,从每个插入中获取一行/对象
>我们将RETURNING id附加到查询中以获取该值
>我们添加一个=> a.id做自动行转换.参见pg-promise returns integers as strings了解这是什么.
UPDATE
对于通过单个INSERT查询的高性能方法,请参见Multi-row insert with pg-promise.