登录
首页 >  Golang >  Go问答

忽视限制子句进行更新

来源:stackoverflow

时间:2024-02-06 15:00:25 398浏览 收藏

从现在开始,努力学习吧!本文《忽视限制子句进行更新》主要讲解了等等相关知识点,我会在golang学习网中持续更新相关的系列文章,欢迎大家关注并积极留言建议。下面就先一起来看一下本篇正文内容吧,希望能帮到你!

问题内容

gorm 似乎不支持将 limit 与 update 结合使用,也不会抛出错误。

resupdate := tx.model(&daos.voucher{}).
            where("status = ?", models.voucherstatusavailable).
            limit(quantity).
                        scan(&vouchers).
            update("status", models.voucherstatusbooked)

此查询会将数据库中的每个字段从 voucherstatusavailable 更新为 voucherstatusbooked,而不考虑 limit 的使用。

有人很快就解决了这个问题:https://penkovski.com/post/gorm-update-returning/ 但他们的解决方案是将 limit 放在 where 子句中:

resUpdate := tx.Model(&daos.Voucher{}).
            Where("status = ? LIMIT ?", models.VoucherStatusAvailable, quantity).
            Update("status", models.VoucherStatusBooked)

使用 gorm 软删除时不起作用,因为它在 where 子句周围放置括号,并在其后面添加 and returned_at = null 过滤器。

最初我使用两个单独的查询(一个选择然后一个更新)来完成此操作,但在这种情况下可能会发生冲突。 有谁知道我应该如何选择表中的 x 成员,然后更新他们的状态,而不会有与所选项目冲突的风险?

编辑:我使用的 dbms 是 postgresql


正确答案


回答了不同的观点:

  1. postgre 不支持 limit 和 order by,因此我需要替代方案。
  2. 正如评论中指出的那样,正确的替代方案似乎是 cte。
  3. gorm 支持自定义插件,并且有一个实现 cte 的插件:https://github.com/WinterYukky/gorm-extra-clause-plugin。不幸的是,它与 update 子句不兼容。
  4. 最终,我找到的唯一解决方案是在原始 sql 中执行 cte:
        var updated []Voucher
        resUpdate := tx.Raw(`WITH v AS (
            SELECT * from vouchers WHERE status = ?
            LIMIT ?
        )
        UPDATE vouchers SET status = ?
        WHERE EXISTS (SELECT * FROM v WHERE vouchers.id = v.id)
        RETURNING *`,
        models.ArticleStatusAvailable, quantity, models.VoucherStatusBooked).
        Scan(&updated)

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>