在Upsert上跳过空值
我正在使用pg-promise来处理我的Postgres查询,而且我遇到了麻烦,find下面的查询的解决scheme:
我正在尝试创build一个批量插入多行的方法,这是我的代码:
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); }),
现在的问题是,在某些情况下,我得到一个或多个字段为空,我希望数据库保留旧值,而不是用空值replace它。
有什么build议么?
使用助手方法来生成查询:
const skipIfNull = name => ({name, skip: c => c.value === null}); const cs = new pgp.helpers.ColumnSet([ '?id', skipIfNull('name'), skipIfNull('age'), skipIfNull('type') ], {table: 'table'});
请参见typesColumnSet和Column 。
从样本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 *
但要注意,按照方法设置的 API,如果所有的条件列都是空的,它将返回一个空string,所以生成的查询将是无效的。 你会想添加一个检查;)
此外,考虑到您正在生成多插入,可以生成一个多行插入,以提供更好的性能。 为此,请参阅使用pg-promise的多行插入 。
也可以看看:
- 用pg-promise跳过更新列