借口似乎可能是重复的。我熟悉Postgres中的多个更新......但我似乎无法找到解决这个问题的方法......
我有一个photos
表,其中包含以下列:id
(主键),url
,sort_order
和owner_user_id
。
我们希望允许用户界面允许用户在集合视图中重新排序现有照片。在这种情况下,当拖动重排序交互完成后,我可以使用以下内容向我们的API发送POST
正文:
req.body.photos = [{id: 345, order: 1, id: 911, order: 2, ...<etc>}]
在这种情况下,我可以转换并在数组中的每个项目的循环中运行以下查询。
photos.forEach(function (item) {
db.runQuery('update photos set sort_order=$1 where id=$2 and owner_user_id=$3', [item.order, item.id, currentUserId])
})
一般来说,在循环中运行数据库查询通常是不受欢迎的,所以无论如何,这可以通过1个查询完成,这将是非常棒的。
提前非常感谢。
答案 0 :(得分:1)
在循环内运行选择查询肯定是有问题的,但我不认为如果您要更新的数据本身不在数据库中,则多个更新必然不受欢迎。但是,要将它们作为单独的事务执行,可能是。
我的建议是将所有已知更新包装在一个事务中。这不仅对数据库更友好(编译一次,执行多次,提交一次),但这是我认为你试图做的ACID方法。如果由于某种原因,您的某个更新失败,它们都会失败。这可以防止您有两张订单为&#34; 1的照片。&#34;
我没有认识到你的语言,但这里有一个例子,说明C#中可能会出现这种情况:
NpgSqlConnection conn = new NpgSqlConnection(connectionString);
conn.Open();
NpgSqlTransaction trans = conn.BeginTransaction();
NpgSqlCommand cmd = new NpqSqlCommand("update photos set sort_order=:SORT where id=:ID",
conn, trans);
cmd.Parameters.Add(new NpgSqlParameter("SORT", DbType.Integer));
cmd.Parameters.Add(new NpgSqlParameter("ID", DbType.Integer));
foreach (var photo in photos)
{
cmd.Parameters[0].Value = photo.SortOrder;
cmd.Parameters[1].Value = photo.Id;
cmd.ExecuteNonQuery();
}
trans.Commit();
我认为在Perl中,它会更简单 - 关闭DBI AutoCommit并在插入后提交。
CAVEAT:当然,添加错误捕获 - 我只是说明了它的外观。
另外,我改变了你更新SQL。如果&#34; Id&#34;是主键,我认为您不需要额外的owner_user_id=$3
子句来使其正常工作。