我有一个场景,我需要插入多个记录。我有一个像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的单个查询中保存列表中的所有项目。我无法从文档中找到任何文档/理解。任何帮助赞赏。感谢。
答案 0 :(得分:28)
我是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
查询承诺,然后将其全部解析为batch。
第二种方法是将所有插入值连接到单个INSERT
查询中,我在Performance Boost中详细解释。另见:Multi-row insert with pg-promise。
有关更多示例,请参阅Tasks和Transactions。
<强>加成强>
值得指出的是,在大多数情况下,我们不会插入记录id
,而是自动生成记录。有时候我们想要恢复新的身份,而在其他情况下我们不在乎。
以上示例使用null
- s数组解析,因为batch使用一系列单独结果进行解析,方法none使用null
进行解析,根据它的API。
我们假设我们想要生成新的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
值RETURNING id
附加到查询中以获取值a => +a.id
来执行自动行转换。另请参阅pg-promise returns integers as strings以了解+
的用途。<强> UPDATE-1 强>
要通过单个INSERT
查询获得高性能方法,请参阅Multi-row insert with pg-promise。
<强> UPDATE-2 强>
必读文章:Data Imports。