【问题标题】:How to use fragment for returning a value when updating in Ecto在 Ecto 中更新时如何使用片段返回值
【发布时间】:2019-01-16 21:22:15
【问题描述】:

我需要在数据库中执行更新并返回一个值。这可以使用PostgreSQL 中的RETURNING 关键字来实现

由于 ecto 不支持此功能,我想我必须使用 fragment,但我不知道该怎么做。这就是我所拥有的:

query = from(v in MyModel, 
 where: v.id == ^instance_id, 
 update: [
   inc: [counter: 1], 
 ]
)

我想在更新后返回一些字段,例如计数器和id,所以我需要在查询中添加:RETURNING id, counter;

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    在 Ecto 3 中,不推荐在 update_all 中使用返回:true 的机会,以支持查询中的选择。所以你会像这样解决它:

    result = from(v in MyModel, where: v.id == ^instance_id, select: {v.id, v.counter})
             |> MyRepo.update_all([inc: [counter: 1]])
    

    【讨论】:

      【解决方案2】:

      如果你使用 Ecto.Repo.update_all https://hexdocs.pm/ecto/Ecto.Repo.html#c:update_all/3 有一个选项 :returning 与返回的字段列表一起传递

      :returning - 选择要返回的字段。如果为 true,则返回给定结构中的所有字段。可能是字段列表,其中仍返回结构但仅返回给定字段。或 false,不返回任何内容(默认值)。并非所有数据库都支持此选项。

      在执行之后你可以访问一个元组:

      它返回一个元组,其中包含条目数和任何返回的结果作为第二个元素。如果数据库不支持 UPDATE 语句中的 RETURNING 或未选择返回结果,则第二个元素将为 nil。

      类似这样的:

      result = from(v in MyModel, where: v.id == ^instance_id)
               |> MyRepo.update_all([inc: [counter: 1]], returning: [id, counter])
      

      【讨论】:

      • 谢谢!这工作得很好。我只需要用Repo.update_all替换MyRepo.update_all
      猜你喜欢
      • 2016-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多