【问题标题】:pg-promise quick way to delete set of tuplespg-promise 删除元组集的快速方法
【发布时间】:2020-09-19 08:32:56
【问题描述】:

有没有更好的写法:

DELETE FROM
    table
WHERE
    _id = $<id>
    AND (
        item_id = $<item_id>
        AND map_id = $<map_id>
        OR
        item_id = $<another_id>
        AND map_id = $<another_map_id>
        ...
    )

我的数据集格式是:

[
    {
        item_id: "some_id",
        map_id: "other_id"
    }
    ...
]

pg-promise 或什至只是简单的postgreSQL 写这个有什么好方法?

【问题讨论】:

    标签: javascript sql postgresql sql-delete pg-promise


    【解决方案1】:
    DELETE FROM table
    WHERE
        _id = $<id>
        AND (item_id, map_id) IN ($<values:raw>)
    

    如果您有以下输入数据:

    const input = [
        {
            item_id: 'some_id',
            map_id: 'other_id'
        }
        ...
    ];
    

    然后您可以使用pg-promise 生成values,如下所示(参见helpers.values):

    const values = pgp.helpers.values(input, ['item_id', 'map_id']);
    

    如果需要更多详细信息,例如类型转换等,您可以将列作为完整的 ColumnSet 传递。

    【讨论】:

    • 因为我也有一个$&lt;id&gt;,我猜我会这样查询:pgp.result(sql_query, { id: 'some id', values } 对吧?
    • @AL 只有当你需要从结果对象中返回一些东西时才使用方法result,例如删除的行数,然后你可以这样做:db.result(sql, {id, values}, r =&gt; r.rowCount),否则,你可以只使用方法none.
    • 是的,我使用rowCount 来确保删除正确的行数,否则我会发送一些错误/警告消息。我也在使用await 所以我不使用函数
    • 那么你将如何定义列?我需要先看看这样的数组,以及你是如何尝试使用它的。无论如何,这是题外话,所以我们不要在这里跑题,这不是评论部分的用途。
    • @A.L 不,您不需要重新映射任何内容。您可以只使用ColumnSet,将每列虚拟化,并重定向源。例如,如果每个这样的数组中有 2 个元素,则 ColumnSet 中的列可以定义为:{ name: 'first', init: c =&gt; c.source[0]}{ name: 'second', init: c =&gt; c.source[1]}
    【解决方案2】:

    Postgres 支持元组相等,所以你可以这样写:

    DELETE FROM table
    WHERE
        _id = $<id>
        AND (item_id, map_id) IN ( 
            ($<item_id>, $<map_id>),
            ($<another_id>, $<another_map_id>),
            ...
        )
    

    【讨论】:

    • 啊,我期待这样的事情,但在所有的噪音中都找不到。如果没有其他人回答,我稍后会标记为答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 2018-04-11
    • 2017-08-19
    相关资源
    最近更新 更多