我正在使用pg-promise来处理我的Postgres查询,我遇到了解决以下查询的麻烦:
我正在尝试创建一个单独批量插入多行的方法, 这是我的代码:
massUpsert: (orgId, entities) => db.tx((t) => {
const queries = [];
entities.forEach((entity) => {
const { id, name, age, type } = entity;
queries.push(
t.one(`INSERT INTO public.table (id, name, age, type)
VALUES ($1, $2, $3, $4)
ON CONFLICT (id) DO update
SET
name = $2,
age = $3,
type = $4
RETURNING *`,
[id, name, age, type]));
});
return t.batch(queries);
}),
现在的问题是,在某些情况下,我为一个或多个字段获取null,并且我希望数据库保留旧值而不是用null替换它。
有什么建议吗?
答案 0 :(得分:1)
使用helpers方法生成查询:
const skipIfNull = name => ({name, skip: c => c.value === null});
const cs = new pgp.helpers.ColumnSet([
'?id',
skipIfNull('name'),
skipIfNull('age'),
skipIfNull('type')
], {table: 'table'});
从示例data
生成查询:
const data = {
id: 1,
name: null, // will be skipped
age: 123,
type: 'tt'
};
const query = pgp.helpers.insert(data, cs) + ' ON CONFLICT(id) DO UPDATE SET ' +
pgp.helpers.sets(data, cs) + ' RETURNING *';
将生成:
INSERT INTO "table"("id","name","age","type") VALUES(1,null,123,'tt')
ON CONFLICT(id) DO UPDATE SET "age"=123,"type"='tt' RETURNING *
但要注意,根据方法set API,如果所有条件列都变成null
,它将返回一个空字符串,因此生成的查询将无效。你需要为它添加一个检查;)
另外,考虑到您正在生成多插入,可以生成一个可提供更好性能的多行插入。为此,请参阅Multi-row insert with pg-promise。
另见: