2011-11-24 48 views
23

我將刪除與另一個表(子)有關係的SQL Server表(父)中的數據。
我試過基本的刪除查詢。但它不工作(我知道它不會)。用SQL Server表中的外鍵刪除數據

DELETE FROM table WHERE ... 

它返回以下錯誤

DELETE語句衝突與基準約束...

我需要保持表的模式。我知道我只需要在查詢中添加一些單詞,以前我曾經這樣做過,但我無法回想起它。

回答

12

如果希望刪除是自動的,則需要更改模式以使外鍵約束爲ON DELETE CASCADE

欲瞭解更多信息,請參閱MSDN page on Cascading Referential Integrity Constraints

ETA(在海報中澄清後):如果無法更新模式,則必須先手動刪除受影響的子記錄。

+0

啊。我錯過了在我的文章中講述這個部分,我必須在不改變模式的情況下才能使用它。有可能吧? – Andha

+1

不,這是不可能的一些神奇的查詢OPTION或其他。您需要手動執行刪除操作。 –

28

您可以禁用和前和刪除後重新啓用外鍵約束:所以

alter table MyOtherTable nocheck constraint all 
delete from MyTable 
alter table MyOtherTable check constraint all 
+5

如果您禁用然後重新啓用約束,由於外鍵引用中斷會導致重新啓用失敗嗎? –

+0

不,它只會在向字段中寫入新值時檢查約束 - 當您將檢查重新放入時,它不會重新掃描整個表。 –

+3

好吧。這意味着子表中的所有數據都將保留在那裏。我即將刪除2k行,如果將數據保存在子表中,我認爲它會很笨重。我想我會手動做。無論如何,答覆球員。你值得+1 :) – Andha

2

,你需要從衝突表或多個邏輯來UPDATE他們FOREIGN KEYDELETE相關行引用其他PRIMARY KEY從父表中刪除。

此外,您可能需要閱讀這篇文章Don’t Delete – Just Don’t

26

您需要手動刪除的孩子們。這兩個查詢的<condition>是相同的。

DELETE FROM child 
FROM cTable AS child 
INNER JOIN table AS parent ON child.ParentId = parent.ParentId 
WHERE <condition>; 

DELETE FROM parent 
FROM table AS parent 
WHERE <condition>; 
+0

這兩個DELETE可以組合在一起嗎?我只需要編寫零件一次? –

+1

我不這麼認爲@ThomasTempelmann。如果您只想寫一次條件,則必須打開級聯刪除,而不是手動處理每個表。 Alastair Maw的答案也引用了這個選項。 –

2

要刪除其parent_child的關係, 首先,你必須通過提聯接然後只需刪除父表中的數據刪除子表中的數據表中的數據,例子如下:

DELETE ChildTable 
FROM ChildTable inner join ChildTable on PParentTable.ID=ChildTable.ParentTableID 
WHERE <WHERE CONDITION> 


DELETE ParentTable 
WHERE <WHERE CONDITION> 
+0

如果您不是級聯刪除,這是最好的答案。遊標執行可怕並刪除約束來刪除可能會留下孤立的行在其他表中。 – Corv1nus

5

這裏您要添加的外鍵爲貴 「子」 表

ALTER TABLE child 
ADD FOREIGN KEY (P_Id) 
REFERENCES parent(P_Id) 
ON DELETE CASCADE 
ON UPDATE CASCADE; 

之後,如果你做的「父」表中刪除查詢這樣

DELETE FROM parent WHERE ..... 

既然孩子有DELETE CASCADE的引用父,「子」行也將被刪除!與「父母」一起。

1

有用的腳本,您可以將數據庫的所有表中刪除所有數據, 你DATABSE名稱替換TT:

declare @tablename nvarchar(100) 
declare c1 cursor for 
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG='tt' AND TABLE_TYPE='BASE TABLE' 

open c1 
fetch next from c1 into @tablename 

while @@FETCH_STATUS = 0 
    begin 
    print @t1 
     exec('alter table ' + @tablename + ' nocheck constraint all') 
     exec('delete from ' + @tablename) 
     exec ('alter table ' + @tablename + ' check constraint all') 
     fetch next from c1 into @tablename 
    end 
close c1 
DEALLOCATE c1