当前位置: 首页 > 面试题库 >

使用pg-promise跳过更新列

骆照
2023-03-14
问题内容

我在Postgres上使用pg-promise的节点上建立了一个API,效果很好,但是我正在考虑如何修改PUT语句以更好地处理输入中的NULLS。

以下是PUT语句的代码:

    //UPDATE a single record
function updateRecord(req, res, next) {
    db.none('update generic1 SET string1=$1,' +
                               'string2=$2,' +
                               'string3=$3,' +
                               'string4=$4,' +
                               'string5=$5,' +
                               'string6=$6,' +
                               'integer1=$7,' +
                               'integer2=$8,' +
                               'integer3=$9,' +
                               'date1=$10,' +
                               'date2=$11,' +
                               'date3=$12,' +
                               'currency1=$13,' +
                               'currency2=$14' +
            'WHERE id = $15',
            [req.body.string1,
             req.body.string2,
             req.body.string3,
             req.body.string4,
             req.body.string5,
             req.body.string6,
             parseInt(req.body.integer1),
             parseInt(req.body.integer2),
             parseInt(req.body.integer3),
             req.body.date1,
             req.body.date2,
             req.body.date3,
             parseInt(req.body.currency1),
             parseInt(req.body.currency2),
             parseInt(req.params.id)])
        .then(function(){
            res.status(200)
                .json({
                    'status': 'success',
                    'message': 'updated one record'
                });
        })
        .catch(function(err){
            return next(err);
        });
}

现在,此语句有效,但是如果我将NULLS传递给下一个更新,它也会删除现有值。例如,如果我只想更新string1和date2,则必须发送整个json对象,否则所有其他值都将设置为NULL。

有没有更好的方法来解决这个问题?我应该改用PATCH动词吗?


问题答案:

我是pg-promise的作者;)

var pgp = require('pg-promise')({
    capSQL: true // capitalize all generated SQL
});

// generic way to skip NULL/undefined values for strings:
function str(col) {
    return {
        name: col,
        skip: function () {
            var val = this[col];
            return val === null || val === undefined;
        }
    };
}

// generic way to skip NULL/undefined values for integers,
// while parsing the type correctly:
function int(col) {
    return {
        name: col,
        skip: function () {
            var val = this[col];
            return val === null || val === undefined;
        },
        init: function () {
            return parseInt(this[col]);
        }
    };
}

// Creating a reusable ColumnSet for all updates:
var csGeneric = new pgp.helpers.ColumnSet([
    str('string1'), str('string2'), str('string3'), str('string4'), str('string5'),
    str('string6'), int('integer1'), int('integer2'), int('integer3'),
    str('date1'), str('date2'), str('date3')
], {table: 'generic1'});

// Your new request handler:
function updateRecord(req, res, next) {

    var update = pgp.helpers.update(req.body, csGeneric) + ' WHERE id = ' +
        parseInt(req.params.id);

    db.none(update)
        .then(function () {
            res.status(200)
                .json({
                    'status': 'success',
                    'message': 'updated one record'
                });
        })
        .catch(function (err) {
            return next(err);
        });
}

参见helpers名称空间;)

另外,您可以对每列进行自己的验证,然后相应地生成UPDATE查询,尽管它不会那么优雅;)

更新

请注意,在库的版本5.4.0中,方式initskip参数化已更改,请参见发行说明。

从5.4.0版开始,您可以简化代码,如下所示:

// generic way to skip NULL/undefined values for strings:
function str(column) {
    return {
        name: column,
        skip: c => c.value === null || c.value === undefined
    };
}

// generic way to skip NULL/undefined values for integers,
// while parsing the type correctly:
function int(column) {
    return {
        name: column,
        skip: c => c.value === null || c.value === undefined,
        init: c => +c.value
    };
}

而且,如果您要跳过根本没有传入的属性,因此甚至不存在于对象中,请使用以下方法:

skip: c => c.value === null || c.value === undefined

你可以这样做:

skip: c => !c.exists

更新

库的5.6.7版本对此选项进行了进一步改进emptyUpdate,当指定此选项时,该选项表示方法要返回的值,而不是throwing Cannot generate an UPDATE without any columns。有关详细信息,请参见helpers.update。

另请参见:ColumnConfig。



 类似资料:
  • 我正在尝试从数据库中加载50000个包含文本的项目,标记它们并更新标签 我使用pg-Promise和pg-query-stream来达到这个目的 我能够让流部分正常工作,但是更新变得有问题,有这么多更新语句 这是我现有的代码 db对象是来自pg promise的对象,而tagger只是从变量标记中包含的文本中提取一个标记数组 根据我在诊断中看到的内容,执行了太多更新语句,有没有办法对它们进行批处理

  • 问题内容: 我有一个需要插入多个记录的场景。我有一个表结构,如id(其他表中的fk),key(char),value(char)。需要保存的输入将是上述数据的数组。示例:我有一些数组对象,例如: 在MS SQL中,我将创建并传递TVP。我不知道如何在postgres中实现。所以现在我要做的是使用pg- promise库将列表中的所有项目保存在postgres sql中的单个查询中。我找不到任何文档

  • 我想使用单个查询插入多行,例如: 是否有一种方法可以轻松做到这一点,最好是针对如下对象数组: 我最终可能会在一个块中有500条记录,因此不希望运行多个查询。 到目前为止,我只能为单个对象执行此操作: 顺便问一个问题:使用< code>${}符号的插入是否可以防止SQL注入?

  • 问题内容: 我想将超时添加到pg- promise查询,以便如果数据库尚未响应,则在一段时间后它们将失败。有什么建议的方法吗?还是我应该做一个可以处理定时器并拒绝诺言的自定义包装器(如果为时已晚)? 问题答案: 来自pg-promise的作者… pg-promise不支持查询取消,因为它可以解决数据库设计错误或查询执行不正确的问题。 PostgreSQL支持在执行耗时的查询时应使用的事件,因此无需

  • 问题内容: 我在了解角度组件范围时遇到麻烦。如果我做类似的事情: 它可以正常打印…现在,如果我做一些小的修改并使其异步: 它不会打印任何内容。我可以使用点击处理程序thouogh来更改值,但是对于http和其他异步操作而言,它将无法正常工作。 问题答案: 运行异步代码时,需要让Angular知道某些内容已更新。这使得angular运行$ digest循环,检查是否需要更新任何绑定。 为此,请将您的

  • 问题内容: 我想用一个查询插入多个行,例如: 有没有一种方法可以轻松地做到这一点,最好是针对这样的对象数组: 我可能最终将500条记录放在一个块中,因此运行多个查询将是不可取的。 到目前为止,我只能对单个对象执行此操作: 附带的问题:使用符号插入是否可以防止SQL注入? 问题答案: 我是pg-promise的作者。 在旧版本的库中,Performance Boost文章中的简化示例涵盖了这一点,在