2012-09-18 136 views
0

我有兩個表具有以下的列:從一個表中刪除並更新另一個

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

我想det_id在ID列表,它可以這樣做,以刪除表DETAILS行:

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

  1. 同時我需要的,如果0更新表

    UPDATE summary SET sum_number-=somefunction(details.det_number) 
    WHERE summary.sum_id=details.sum_id 
    
  2. 更多了,以後這將是完全很大,從SUMMARY表中刪除行如果sum_number<=0

如何做到這一切的一種智能的方式?

如果我知道,從一開始,這兩個標識:details.det_id(刪除)和summary.sum_id對應於details.det_id

+1

你正在使用什麼SQL引擎/方言 - MySQL,MS SQL,PostgreSQL?它支持事務,觸發器,存儲過程等嗎? – Artemix

+0

我寧願避免像觸發器或存儲過程那樣違法 – Stan

+0

由於您不想使用任何SQL擴展,因此最好的方法是逐步執行這三個操作。在這種情況下,最聰明的方式是在一次交易中執行它們。 – Artemix

回答

1

您沒有指定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_summary CTE實際上在聲明中使用。此外,它可能會提高性能,因爲只檢查已更改的彙總行(不是全部)。

+0

這很好,但不幸的是我不知道DBMS提前:(事實上,我不得不讓它工作,不管SQL引擎/方言 – Stan

+0

@Stan:使它與DBMS獨立僅僅意味着它將在所有引擎上運行同樣緩慢/不良。你應該考慮DBMS特定的解決方案,它比'select * from foo'更復雜。 –

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 
+0

你怎麼能確定沒有其他方法呢? – askmish

+0

假設OP使用T-SQL方言,根本不知道(至少據我所知),只使用一條語句從兩個表中刪除。也許通過一些適當的觀點來實現這一點,原則上可以實現,但我認爲這種做法違背了以智能方式實施這一點。 – Dan

0

我會使用觸發器......然後數據庫負責刪除。

使用更新觸發器,一次/如果更新成功,如果將觸發可以儘可能多或少的觸發器,即可以做到2次刪除。

有關示例有這樣的教程的一個讀:

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