2012-06-14 53 views
2

我試圖從兩個不同的表中同時刪除行。這些表是這個樣子:從兩個表中刪除行

TABLE - Value 
----------- 
ID 
Field 
<some other stuff...> 

TABLE - Srch 
----------- 
Value_ID 
Srch_ID 
<some other stuff...> 

我試圖從VALUE刪除所有的行,其中field等於「成功」,也從SRCH是通過value_idVALUE刪除行。在SRCH中可以有多行,並且具有相同的value_id

此SQL語句的外觀如何?

+2

我想說你有3個選項。 1)在另一個表上爲你刪除的觸發器2)表之間的外鍵和刪除級聯上的使用3)刪除一個你可以控制所採取行動的程序/包。每個人都有自己的優點和缺點。例如,級聯將始終發生。觸發器可以在它發生的時候流露出一定的控制權,因爲某些業務規則要求你保留孩子,一個包/過程只有在被調用時纔是好的,所以不調用它的東西不會刪除孩子;但是這爲您提供了最大的靈活性。 – xQbert

+0

理想情況下,答案應該用於回答問題,而不是評論。 –

回答

3

雖然改變數據庫自動完成,這是理想的,如果這是永遠是你想要的行爲,你有權限數據庫這樣做。

否則,尤其是如果這是一次性的或偶然的事情,也可以是一組2個簡單的查詢完成後,運行起來:

Delete from Srch where value_id in (Select ID from value where field='SUCCESS') 
Delete from value where field='SUCCESS' 

如果這是一個活的系統,要運行這些作爲單個交易的一部分,以便您在兩個陳述之間沒有更新的值,離開孤兒或類似的東西。如果以正確的隔離級別運行,這將是您最簡單,最簡單的方式。

5

我推薦在你的2個表和ON DELETE CASCADE之間使用外鍵。因此,您只需刪除Value中的行,並刪除Srch中所有對應的行。

您可以在以下約束添加到您的數據庫:

ALTER TABLE Srch ADD CONSTRAINT 
FK_Value_ID FOREIGN KEY(Value_ID) 
REFERENCES Value (ID) 
ON DELETE CASCADE; 

只要是明確的(從xQbert評論引號):「級聯總是會發生」時從值的ID被刪除。

+0

這會起作用。您的其他選項是兩個刪除語句作爲同一事務的一部分。 'DELETE FROM SRCH where value_id =:x; DELETE FROM VALUE where value_id =:x;'出錯時,只需回滾事務。 –

+0

如果用戶有權這樣做,他們可能不這樣做。此外,這將需要始終需要,並觸發數據庫的人(甚至程序)有權訪問更改數據應該非常小心! –

0

或更復雜的解決方案使用PL/SQL,但沒有外鍵:

DEFINE 
v_success_count number; 
v_val_id number; 
BEGIN 

SELECT INTO v_success_count count(*) FROM 


WHILE (select count(*) FROM value WHERE field = 'SUCCESS') > 0 
LOOP 
    SELECT value_id INTO val_id FROM value WHERE field = 'SUCCESS' AND rownum = 1; 

    DELETE FROM srch WHERE value_id = v_val_id; 

    DELETE FROM value WHERE field = 'SUCCESS' AND rownum = 1; 
END LOOP 
COMMIT; 
END;