2009-09-18 181 views
0

我有兩個表,Table1和Table2具有相同的主鍵(FKTestID)。
如果我想刪除表1中的一行,並且相同的FKTestID在表2中,它將不起作用。如果Table1.FKTestID不等於表2中的任何FKTestID,則只能從Table1中刪除一行。Sql Server 2008檢查約束

請幫我解決這個問題嗎?

+0

你能顯示當前約束嗎? – JeffO 2009-09-18 14:40:30

回答

3

您需要設置約束級聯刪除。

您可以通過修改約束來通過SQL管理工作室完成此操作。

或者你也可以通過SQL當您通過包括ON DELETE CASCADE

您也可以與ALTER TABLE command做創建約束做到這一點。

+2

我傾向於不使用CASCADE刪除;這有點危險。我希望代碼必須知道首先刪除引用的FK明確 – 2009-09-18 14:44:56

+0

是的,我同意級聯刪除不是最好的事情。我從來沒有在實時數據庫中使用過它們,儘管我可以看到它們在某些情況下有一席之地。似乎級聯刪除是OP之後的內容。 – 2009-09-18 15:12:27

+1

我遠離級聯delte becasue,如果您需要刪除大量記錄,可能會導致性能問題。 – HLGEM 2009-09-18 15:21:43

2

下面是一個代碼示例,實現了Simon在上面提出的建議。

CREATE TABLE dbo.Table1 (
    FKTestID int NOT NULL PRIMARY KEY 
) 
GO 

CREATE TABLE dbo.Table2 (
    FKTestID int NOT NULL PRIMARY KEY 
) 
GO 

ALTER TABLE dbo.Table2 
ADD CONSTRAINT FK_Table2_FKTestID 
FOREIGN KEY (FKTestID) 
REFERENCES dbo.Table1 (FKTestID) 
ON DELETE CASCADE 
GO 

INSERT INTO dbo.Table1 VALUES (1) 
INSERT INTO dbo.Table2 VALUES (1) 
INSERT INTO dbo.Table1 VALUES (2) 
INSERT INTO dbo.Table2 VALUES (2) 

DELETE FROM dbo.Table1 WHERE FKTestID = 1 

SELECT 'Table1' AS [Table], * FROM dbo.Table1 
SELECT 'Table2' AS [Table], * FROM dbo.Table2 

============================================= 

Table  FKTestID 
------ ----------- 
Table1   2 

Table  FKTestID 
------ ----------- 
Table2   2 

請注意,我同意Mitch Wheat對CASCADE DELETE的評論是危險的。這個功能很有趣,但我從來沒有在生產系統中使用它。

0

如果您問的是如何擺脫約束條件以便刪除,請不要考慮這樣做。約束是有原因的。如果您不知道原因,請不要刪除它。

其他人建議添加級聯刪除。我建議這是一個糟糕的主意,因爲你可能會導致數據庫性能問題。最好編寫一個腳本,以正確的順序刪除記錄。在這種情況下,您需要先刪除表2中的匹配記錄,然後運行表1中的刪除。

您還需要先評估表2中的數據,然後再決定是通過腳本還是通過級聯delte刪除它。如果你不應該從表2中刪除這些記錄,那麼你不應該從表1中刪除記錄(通過刪除約束),因爲這將使表2記錄成爲孤兒,你將失去數據的完整性(應該成爲您在任何數據庫操作中的首要關注點(安全性和性能非常接近第二和第三))。

讓我給你一個場景,表2中的數據表明你不應該刪除記錄。假設你有一個顧客表和訂單表。您想要刪除客戶A,但他有過去的訂單。如果您刪除了兩個記錄,您將弄亂訂單上的所有會計信息。如果您刪除客戶而不是訂單(通過消除約束),那麼您有一個命令,您不能再告知發送給誰。在這種情況下要做的正確事情是在customers表中有一個ISactive文件,並將其標記爲非活動客戶。您當然需要重新設計搜索客戶信息的代碼,以確保其包含標誌以僅選擇活躍的客戶,這就是爲什麼這種事情應該在開發之初不要遲到(爲什麼它是值得您花時間聘請數據庫專家進行設計階段,因爲許多應用程序開發人員在設計過程中不考慮隨時間推移維護數據)。