Postgresql 使用EXTO交换具有唯一约束的值的正确方法?
我需要交换具有唯一约束的值。我正在尝试使用update_all函数,如下所示Postgresql 使用EXTO交换具有唯一约束的值的正确方法?,postgresql,elixir,phoenix-framework,ecto,Postgresql,Elixir,Phoenix Framework,Ecto,我需要交换具有唯一约束的值。我正在尝试使用update_all函数,如下所示 from(e in Episode, where: e.show_id == ^id, update: [set: [position: fragment("position + 1")]]) |> Repo.update_all([]) 使用此选项时,由于位置重复,我出现了一个错误: ERROR (unique_violation): duplicate key value violates unique c
from(e in Episode, where: e.show_id == ^id, update: [set: [position: fragment("position + 1")]])
|> Repo.update_all([])
使用此选项时,由于位置重复,我出现了一个错误:
ERROR (unique_violation): duplicate key value violates unique constraint "position_show_id_index"
table: episodes
constraint: position_show_id_index
Key ("position", show_id)=(2, 27) already exists.
如何同时交换这些位置值?通常,在SQL中没有“好”的方法来交换唯一的索引值
是1)删除并重新插入行,或2)在更新两行之前将行更新为另一个placholder值
你可以采取类似的方法,比如:
解决方案1:
eposion=Repo.get(eposion,id)
下一集=Repo.get\u by(集,位置:集.位置+1)
如果是下一集,则执行:回购.删除(下一集)
插曲
|>插曲.变更集(%{position:插曲.位置+1})
|>Repo.update()
如果下一集是什么
回购插入(%Spidence{next|U Spidence | position:Spidence.position})
结束
解决方案2:
(您需要选择一些“不可能”的值作为占位符。例如,如果位置必须为正数,则可以使用负数)
eposion=Repo.get(eposion,id)
下一集=Repo.get\u by(集,位置:集.位置+1)
如果下一集是什么
下一集
|>事件.变更集(%{position:-1})
|>Repo.update()
结束
插曲
|>插曲.变更集(%{position:插曲.位置+1})
|>Repo.update()
如果下一集是什么
下一集
|>插曲.changeset(%{position:插曲.position})
|>Repo.update()
结束
第二种解决方案可能更可取,如果您有任何引用
插曲的外键约束
,我认为一种方法是使用一个事务,首先检查,可能删除以前的记录,然后插入一个新记录。