2011-06-07 188 views
235

我有2个表:T1和T2,它们是现有的数据表。我们在T1和T2之间有一对多的关系。如果删除T1中的记录,则在SQL Server中执行级联删除时,如何更改表定义以执行级联删除,同时删除T2中的所有关联记录。如何使用SQL Server级联删除?

它们之间存在外部约束。我不想删除表格或创建一个触发器来执行T2的删除操作。例如,当我删除一名员工时,所有审核记录也应该消失。

T1 - 员工,

Employee ID  
Name 
Status 

T2 - 绩效评估,

Employee ID - 2009 Review 
Employee ID - 2010 Review 

回答

39

使用类似

ALTER TABLE T2 
ADD CONSTRAINT fk_employee 
FOREIGN KEY (employeeID) 
REFERENCES T1 (employeeID) 
ON DELETE CASCADE; 

填写正确的列名,你应该设置。正如mark_s正确说明的那样,如果你已经有了外键约束,你可能需要先删除旧外键,然后创建新外键。

+36

@marc_s - 实际上,您可以针对两侧的完全相同的列添加第二个外键,并且它将正常工作。如果在没有停机的生产环境中工作,可能最好将级联引入新的FK,然后丢弃旧的FK,而不是在没有FK时留下一个窗口。 (刚刚在SQL 2008上测试过) – 2011-06-07 07:50:20

+0

这是正确的。我尝试了这一点,它的工作原理。没有必要放弃第一个外键约束。谢谢回复。 – 2011-06-08 03:39:14

289

您需要,

  • 除去现有外键约束,
  • 添加一个新的启用了ON DELETE CASCADE设置。

喜欢的东西:

ALTER TABLE dbo.T2 
    DROP CONSTRAINT FK_T1_T2 -- or whatever it's called 

ALTER TABLE dbo.T2 
    ADD CONSTRAINT FK_T1_T2_Cascade 
    FOREIGN KEY (EmployeeID) REFERENCES dbo.T1(EmployeeID) ON DELETE CASCADE 
+3

另一点赞成硬删除软删除 – jbd 2016-03-09 22:09:45

12

第一款能够ONCascade属性:

1.Drop现有的外键约束

2.加一个新的与ON DELETE启用CASCADE设置

例如:

IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Response')) 
BEGIN 

ALTER TABLE [dbo].[Response] DROP CONSTRAINT [FK_Response_Request] 

ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request] FOREIGN KEY([RequestId]) 
REFERENCES [dbo].[Request] ([RequestId]) 
ON DELETE CASCADE 
END 

ELSE 

BEGIN 
ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request] FOREIGN KEY([RequestId]) 
REFERENCES [dbo].[Request] ([RequestId]) 
ON DELETE CASCADE 
END 

二要禁用ONCascade属性:

1.Drop现有的外键约束

2.增加一个新的与ON DELETE NO ACTION设置启用

例如:

IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.Response')) 
BEGIN 
ALTER TABLE [dbo].[Response] DROP CONSTRAINT [FK_Response_Request] 

ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request] FOREIGN KEY([RequestId]) 
REFERENCES [dbo].[Request] ([RequestId]) 
ON DELETE CASCADE 
END 

ELSE 

BEGIN 
ALTER TABLE [dbo].[Response] WITH CHECK ADD CONSTRAINT [FK_Response_Request] FOREIGN KEY([RequestId]) 
REFERENCES [dbo].[Request] ([RequestId]) 
ON DELETE NO ACTION 
END 
133

您可以使用SQL Server Management St UDIO。

→右键单击表格设计并转到关系,然后在左侧窗格和右侧窗格中选择外键,展开菜单“插入和更新规范”并选择“级联”作为删除规则。

SQL Server Management Studio

+0

嗨,有什么区别4,是否转动级联使它很容易删除表中的所有数据。如何查看此表上的所有依赖项/ fk键*,而不是从此表中查看。即使在删除所有FK后,我仍然得到一个错误 – aggie 2015-11-30 19:29:39

+0

@aggie - 你可以检查依赖关系 - 右键单击​​表 - >“查看依赖关系” 此外,sql server会给你详细的错误,像这样的表名和列名“DELETE语句与参考约束”FK_Child1_Parent1“冲突。数据库”TESTDB“中发生冲突,表”dbo“。Child1“,”Parent1ID“列。” – 2015-12-01 05:59:37

+0

@aggie - 第四种情况“设置默认值”是,您必须在外键列中设置默认约束,当我们删除父对象时,默认值将在子表中被替换。 (注意:默认值必须与父表匹配。)有关详细信息,请访问https://www.mssqltips.com/sqlservertip/2365/sql-server-foreign-key-update-and-delete-rules/ – 2015-12-01 06:18:54

177

要添加“级联删除”在SQL Server Management Studio中现有的外键:

。首先,选择外键,然后打开它的“删除并创建要。”一个新的查询窗口。

enter image description here

然后,只需添加ON DELETE CASCADEADD CONSTRAINT命令:

n 并点击 “执行” 按钮来运行此查询。

顺便说一句,让你的外键的列表,看看哪些已经“级联删除”开启时,您可以运行此脚本:

SELECT 
    OBJECT_NAME(f.parent_object_id) AS 'Table name', 
    COL_NAME(fc.parent_object_id,fc.parent_column_id) AS 'Field name', 
    delete_referential_action_desc AS 'On Delete' 
FROM sys.foreign_keys AS f, 
    sys.foreign_key_columns AS fc, 
    sys.tables t 
WHERE f.OBJECT_ID = fc.constraint_object_id 
AND t.OBJECT_ID = fc.referenced_object_id 
ORDER BY 1 

而且如果你发现,你可以“T DROP特定表由于外键约束,但你不能工作了这FK是造成问题,那么你可以使用我在这里提供的SQL:

How can I list all foreign keys referencing a given table in SQL Server?

的SQL在那篇文章中列出了所有引用的FK一个特定的表格。

希望这一切都有所帮助。

特别是长指。

+16

[先生神奇](https://en.wikipedia.org/wiki/Mister_Fantastic)手指恐慌。 – ruffin 2017-10-19 16:22:45

+27

lol在手指:D – Cloud 2017-10-23 08:59:51

+6

当我看到那个手指时,我的心沉入恐惧中 – BDillan 2017-12-14 15:38:47

-5

我认为你不能只删除tables属性如果这是实际的生产数据,只是删除不影响表模式的内容。

5

ON DELETE CASCADE
它指定当父数据被删除时子数据被删除。

CREATE TABLE products 
(product_id INT PRIMARY KEY, 
    product_name VARCHAR(50) NOT NULL, 
    category VARCHAR(25) 
); 

CREATE TABLE inventory 
(inventory_id INT PRIMARY KEY, 
    product_id INT NOT NULL, 
    quantity INT, 
    min_level INT, 
    max_level INT, 
    CONSTRAINT fk_inv_product_id 
    FOREIGN KEY (product_id) 
    REFERENCES products (product_id) 
    ON DELETE CASCADE 
); 

对于这个外键,我们已指定ON DELETE CASCADE子句告诉SQL Server中的子表中删除相应的记录,当父表中的数据被删除。因此,在此示例中,如果从产品表中删除了product_id值,则库存表中使用此product_id的相应记录也将被删除。