在更新插入时跳过空值

2023-11-29

我正在使用 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);
}),

现在的问题是,在某些情况下,我的一个或多个字段为空,并且我希望数据库保留旧值,而不是用空值替换它。

有什么建议么?


Use the 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'});

查看类型列集 and 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 *

UPDATE:新语法通过分配列sets方法。

但请注意,按照方法setAPI,如果所有条件列都是,它将返回一个空字符串null,因此生成的查询将无效。您需要为此添加一个检查;)

此外,考虑到您正在生成多插入,可以仅生成一个多行插入,从而提供更好的性能。为此请参阅使用 pg-promise 进行多行插入.

也可以看看:

  • 使用 pg-promise 跳过更新列
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在更新插入时跳过空值 的相关文章

随机推荐