1

我有两个包含以下列的表:

SUMMARY(sum_id, sum_number) and DETAILS(det_id, det_number, sum_id)

我想从DETAILSID 列表中具有 det_id 的表中删除行,可以通过以下方式完成:

DELETE FROM details WHERE det_id in (1,2,3...)

  1. 同时我需要更新表SUMMARY如果summary.sum_id=details.sum_id

    UPDATE summary SET sum_number-=somefunction(details.det_number) 
    WHERE summary.sum_id=details.sum_id
    
  2. SUMMARY此外,如果之后从表中删除行会非常棒sum_number<=0

如何以智能的方式完成这一切?

如果我从一开始就知道两个 ID:(details.det_id删除)ANDsummary.sum_id对应于details.det_id

4

3 回答 3

2

您没有指定 DBMS,所以我假设是 PostgreSQL。

您可以使用新的可写 CTE 功能通过单个语句执行此操作:

with deleted as (
   delete from details
   where det_id in (1,2,3...)
   returning details.*
),
new_summary as (
   update summary 
      set sum_number = some_function(deleted.det_number)
   from deleted
   where delete.sum_id = summary.sum_id
   returning summary.sum_id
) 
delete from summary 
where sum_number <= 0
and sum_id in (select sum_id from new_summary);

外部删除中的in条件不是绝对必要的,但您可能没有不使用的 CTE 定义,因此该条件确保new_summaryCTE 实际用于语句中。此外,它可能会稍微提高性能,因为只检查更改的摘要行(不是全部)。

于 2012-09-18T12:21:56.560 回答
0

不可能在单个语句中执行所有这些操作。你必须做这样的事情:

UPDATE summary SET sum_number = somefunction(details.det_number)
FROM summary INNER JOIN details ON summary.sum_id = details.sum_id

DELETE FROM details WHERE det_id IN (1,2,3,...)

DELETE FROM summary WHERE sum_number <= 0
于 2012-09-18T10:48:48.877 回答
0

我会使用触发器......然后数据库负责删除。

使用更新触发器,一旦/如果更新成功,如果将触发触发器,它可以根据您的需要执行尽可能多或尽可能少的操作……即它可以执行 2 次删除操作。

例如阅读本教程:

http://www.mysqltutorial.org/create-the-first-trigger-in-mysql.aspx这个答案(http://stackoverflow.com/questions/6296313/mysql-trigger-after-update-only-if-来自stackoverflow 的row-has-changed)也提供了一个很好的例子。

于 2012-09-18T10:55:55.363 回答