简体   繁体   English

SQL Server 2008检查约束

[英]Sql Server 2008 check constraint

I have two tables, Table1 and Table2 with same primary key (FKTestID). 我有两个表,表1和表2具有相同的主键(FKTestID)。
If I want to delete one row in Table1 and same FKTestID are in Table2 it will not work. 如果我要删除表1中的一行并且表2中的FKTestID相同,则它将无法工作。 You can only delete a row from Table1 if Table1.FKTestID not equals any FKTestID in Table2. 如果Table1.FKTestID不等于Table2中的任何FKTestID,则只能从Table1中删除一行。

Please help me with this constraint? 请帮我这个限制吗?

You need to set the constraint to cascade on delete. 您需要将约束设置为在删除时级联。

You can do this through SQL management studio by modifying the constraint. 您可以通过修改约束来通过SQL Management Studio执行此操作。

Or you can do this via SQL when you created the constraint by including ON DELETE CASCADE at the end 或者,您可以在创建约束时通过SQL来完成此操作,方法是在最后添加ON DELETE CASCADE

You could also do it with the ALTER TABLE command . 您也可以使用ALTER TABLE命令执行此操作

Here is a code sample implementing what Simon suggested above. 这是一个代码示例,实现了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

Note that I agree with Mitch Wheat's comment about CASCADE DELETE being dangerous. 请注意,我同意Mitch Wheat关于CASCADE DELETE危险的评论。 This feature is interesting, but I have never, ever used it in a production system. 此功能很有趣,但我从未在生产系统中使用过它。

If you are asking how to get rid of the constraint so that you can delete, DO NOT consider doing that. 如果您要问如何摆脱约束以便可以删除,请不要考虑这样做。 The constraint is there for a reason. 约束在那里是有原因的。 If you don't know the reason, don't delete it. 如果您不知道原因,请不要删除它。

Others have suggested adding a cascade delete. 其他人建议添加级联删除。 I suggest that this is poor idea as you can cause performance problems on the database. 我建议这不是一个好主意,因为这可能会导致数据库性能问题。 It is better to write a script that deletes the records in the correct order. 最好编写一个脚本,以正确的顺序删除记录。 In this case you need to delete the matching records from tables2 first, then run the delete on table 1. 在这种情况下,您需要先从table2中删除匹配的记录,然后在表1上运行delete。

You also need to evaluate the data in table2 before deciding to delete from it either by script or by cascade delte. 您还需要评估table2中的数据,然后再决定通过脚本还是通过层叠delte从表2中删除数据。 If you should not be deleting those records from table2, then you should not be delting the records from table1 (by removing the constraint) as this will casue the table 2 records to be orphaned and you will lose the integrity of the data (which should be your first concern in any database actions (security and performance being a very close second and third)). 如果您不应该从表2中删除这些记录,那么您不应该从表1中删除记录(通过除去约束),因为这将导致表2的记录成为孤立记录,并且您将丢失数据的完整性(在任何数据库操作中成为您的首要考虑(安全性和性能紧随其后)。

Let me give you a scenario where the data in table 2 would indicate you should not delete the record. 让我给您一个场景,表2中的数据将指示您不应删除该记录。 Suppose you have a customer table and and order table. 假设您有一个客户表和订单表。 You want to delete customer A, but he has an order in the past. 您要删除客户A,但他过去有一个订单。 If you delete both records, you will mess up all the accounting information on orders. 如果删除两个记录,则会使订单上的所有会计信息混乱。 If you delete the customer but not the order (by eliminating the constraint), then you have an order that you can no longer tell who it was sent to. 如果您删除客户但不删除订单(通过消除约束),那么您将无法再知道将订单发送给谁。 The correct thing to do in a case like this is to have an ISactive file in the customers table and mark him as an inactive customer. 在这种情况下,正确的做法是在客户表中有一个ISactive文件,并将其标记为非活动客户。 You would of course need to redesign the code that searches for customer information to make sure it includes the flag to only select active customers which is why this sort of thing should be thought out at the beginning of development not later (one reason why it is worth your while to hire database specialists for the design phase as many application developers don't consider maintaining the data over time as part of their design process). 当然,您将需要重新设计搜索客户信息的代码,以确保其中包括仅选择活跃客户的标志,这就是为什么应该在开发之初而不是以后考虑这种事情的原因(这是为什么?值得您花时间聘请数据库专家进行设计阶段,因为许多应用程序开发人员在其设计过程中并未考虑长期维护数据)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM