2009-09-18 182 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文件,并将其标记为非活动客户。您当然需要重新设计搜索客户信息的代码,以确保其包含标志以仅选择活跃的客户,这就是为什么这种事情应该在开发之初不要迟到(为什么它是值得您花时间聘请数据库专家进行设计阶段,因为许多应用程序开发人员在设计过程中不考虑随时间推移维护数据)。