使用多个`where`个案

时间:2016-12-21 03:01:59

标签: postgresql

借口似乎可能是重复的。我熟悉Postgres中的多个更新......但我似乎无法找到解决这个问题的方法......

我有一个photos表,其中包含以下列:id(主键),urlsort_orderowner_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个查询完成,这将是非常棒的。

提前非常感谢。

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子句来使其正常工作。