2012-09-22 251 views
1

我有三個表:刪除記錄

PERSON 
-ID_PERSON 
-NAME 
-SURNAME 

PERSON_ADDRESS 
-ID_PERSON 
-ID_ADDRESS 

ADDRESS 
-ID_ADDRESS 
-NR_LOCAL 
-NR_HOME 
-PLACE 

我想刪除與ADRESS表中的所有記錄,其中id_person = 1個

我的查詢(在Oracle)

DELETE * FROM address INNER JOIN person_addres ON 
address.id_address=person_addres.id_address 
WHERE person_addres.id_person=1 ; 

回答

-1

嘗試做一個子選擇 - 對不起我的Oracle是生鏽:

DELETE * FROM address WHERE id_address IN (SELECT id_address FROM person_address WHERE id_person = 1) 
+0

我認爲你必須刪除'*' –

+0

我在想,太... – endyourif

+0

謝謝,我解決這個問題的方法(documenaction),謝謝。 – dexter90

-1

首先從person_id = 1的人員地址中選擇地址標識,然後從地址i等於先前查詢結果的地址中刪除該行。這是所有

DELETE * FROM ADDRESS WHERE ID_ADDRESS IN (SELECT ID_ADDRESS FROM PERSON_ADDRESS WHERE ID_PERSON='1') 
+0

刪除從(選擇*從地址aa JOIN person_address oa ON aa.id_adres = oa.id_adres WHERE oa.id_person = 1) 刪除記錄與表person_address :( – dexter90

0

「我想與ADRESS表中刪除所有記錄,其中id_person = 1」

你有Person和地址之間的許多一對多的關係。這意味着您將刪除id_person != 1的人員使用的地址記錄。這就是你真正想做的事情嗎?

。假定是這樣的話,你需要做的這三個步驟:

  1. 得到person_addressid_address所有的值,其中id_person=1
  2. 刪除所有person_address
  3. 匹配的記錄全部刪除匹配的記錄在address

在Oracle中你可以在兩個狀態使用批量操作和預定義的ODCINUMBERLIST集合(我希望您的ID是數字)。

declare 
    addr_nt ODCINUMBERLIST; 
begin 
    delete from person_address 
    where id_person=1 
    returning id_address bulk collect into addr_nt; 

    forall i in addr_nt.first..addr_nt.last 
     delete from address 
     where addr_id = addr_nt(i); 
end; 

當然,如果你沒有你的表之間定義的外鍵就可以按照其他建議,並愉快地距離address表中刪除。您的數據將是腐敗和不可靠的,但這是不執行關係完整性的代價。

+0

謝謝我明白,但我寫的SQL不是PL/SQL和我將這個命令複製到Acces MS因爲我正在編寫應用程序databse。我很有趣簡單的解決方法:)幫助:) – dexter90

+1

您應該在您的問題中指定* all *您的要求,而不是稍後在評論中添加它們。 – APC

0

表person_address 應該具有對錶人員和地址的外鍵約束。 要優雅地刪除一個人,請考慮使用此程序。

儘管我個人從不會刪除個人詳細信息,但在表中具有人員狀態的人員(例如「活動」或「非活動」)。

create or replace procedure remove_person(p_id_person in person.id_person%type) 
is 
begin 
    delete from person where id_person = p_id_person; 
    delete from address where id_address in (select id_address from person_address where id_person = p_id_person); 
    delete from person_address where id_person = p_id_person; 

-- no exception handling, I want to know when this fails 
end; 

然後,使用這樣的:

begin 
    remove_person(1); 
end; 
+1

我個人認爲你錯了。邏輯刪除引入了錯誤的可能性,使查詢和關係完整性複雜化,甚至可能導致性能問題。正確的做法是從物理上刪除PERSON,對任何記錄進行ADDRESS,並使用審計或歷史記錄表來記錄詳細信息。 – APC

+0

此外,沒有聲明要求刪除PERSON記錄。如果每個PERSON_ID有多個ADDRESS,並且假定該模型實現M:N關係是一種極有可能的情況,那麼您的代碼將失敗。 – APC

+0

好點。我調整了我的程序以考慮M:N關係。那裏太快了。 ;) 邏輯刪除對我來說很好,但審計或歷史記錄表也可以正常工作。一個品味imo的問題。 (不是我期望TS總是使用這個,因爲他似乎沒有在真正的數據庫上工作。) – winkbrace

1

在你的情況personaddress表有許多一對多的關係。這意味着一個人可以同時擁有多個地址和一個地址,可能屬於多個人。您想要刪除某個人的地址,並且想從address表中刪除該地址。我們來考慮以下情況。根據person_address表,ID = 1的人具有ID = 2的地址,ID = 2的人具有相同的地址(ID = 2)。如果您刪除了與#1人(ID = 1)相關的地址記錄,會發生什麼情況? 2號人將被留下沒有地址,或者你會得到integrity constraint violated(取決於你的on delete選項)。

要刪除特定人員的地址,請將其他人的地址保持原樣,最好從person_address表中刪除記錄,而不是address。並且只有在沒有人分配了該地址的情況下,才從address表中刪除記錄。

要刪除特定人員(本例中ID = 1的人員)的所有「地址」(來自person_address表格的所有記錄),可以使用以下SQL。

delete 
    from (select q.id_person 
      from address t 
      join person_address q 
      on (q.id_address = t.id_address) 
     ) x 
    where x.id_person = 1