MySQL外键设置 级联删除
. cascade方式
在父表上update/delete记录时,同步update/delete掉子表的匹配记录
. set null方式
在父表上update/delete记录时,将子表上匹配记录的列设为null
要注意子表的外键列不能为not null
. No action方式
如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作
. Restrict方式
同no action, 都是立即检查外键约束
. Set default方式
父表有变更时,子表将外键列设置成一个默认的值 但Innodb不能识别
在这里我建立两张表:“ProductCategory”,“Product”.
有一个需求是这样的:在删除某个ProductCategory 的时候,同时删除该Category的products.
这里是创建两张表的脚本:
CREATE TABLE [dbo].[ProductCategory]( [Id] [uniqueidentifier] NOT NULL, [Name] [varchar](50) NULL, CONSTRAINT [PK_ProductCategory] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
CREATE TABLE [dbo].[Product]( [Id] [uniqueidentifier] NOT NULL, [CategoryId] [uniqueidentifier] NULL, [Name] [varchar](50) NULL, [Price] [decimal](18, 0) NOT NULL, CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
创建后的表大致如下:
一些实验数据:
INSERT INTO [Test].[dbo].[ProductCategory] VALUES('4B07A7D0-B56A-4DE3-9F55-972AC6D60994','category1'); INSERT INTO [Test].[dbo].[Product] VALUES(newid(),'4B07A7D0-B56A-4DE3-9F55-972AC6D60994','product1','1'); INSERT INTO [Test].[dbo].[Product] VALUES(newid(),'4B07A7D0-B56A-4DE3-9F55-972AC6D60994','product2','2'); INSERT INTO [Test].[dbo].[Product] VALUES(newid(),'4B07A7D0-B56A-4DE3-9F55-972AC6D60994','product3','3'); INSERT INTO [Test].[dbo].[Product] VALUES(newid(),'4B07A7D0-B56A-4DE3-9F55-972AC6D60994','product4','4');
有很多种方法可以实现这个功能:
在模型层中处理:
public class ProductCategoryRepository { public bool DeleteCategory(ProductCategory category) { // 删除Category // 删除该Category 下面的products. } }
这个比较简单也很容易理解,但是它有个问题:如果是直接通过执行SQL 来删除Category的。那么这个约束就无法满足了,或者是说你必须记得如果要删除Category的话,那么就应该使用DeleteCategory方法。
于是第二种方法出现了:
通过触发器来级联删除:
具体的触发器代码如下:
Create TRIGGER [dbo].[DeleteRelatedProducts] ON [dbo].[ProductCategory] AFTER DELETE AS BEGIN SET NOCOUNT ON; delete from [dbo].[product] where categoryId in ( select id from deleted ) END
这种方式比较简单,而且语法也很明了:
具体资料可以参照:http://msdn.microsoft.com/en-us/library/ms191300(SQL.105).aspx
还有一种方式可能并不是很多人知道:
外键的级联删除和更新:
在sql server 中可以通过设置外键的级联删除和更新来实现这个功能。
这里是外键的定义:来自http://baike.baidu.com/view/68073.htm
简介
外键(Foreign Key)
如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的联系。以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表。外键又称作外关键字。换而言之,如果关系模式R中的某属性集不是R的主键,而是另一个关系R1的主键则该属性集是关系模式R的外键,通常在数据库设计中缩写为FK。
外键的作用
保持数据一致性,完整性,主要目的是控制存储在外键表中的数据。 使两张表形成关联,外键只能引用外表中的列的值或使用空值
我们现在的要求是删除ProductCategory的时候,同时删除该ProductCategory下面的Product。
所以应该在Product 表中建立外键约束,
看到删除规则了吗,指定为层叠的话,那么当删除ProductCategory的时候,就会删除Product了。
select * from ProductCategory; select * from product; Delete from ProductCategory; select * from ProductCategory; select * from product;
结果如下:
- mysql如何设置主键和外键,实现级联更新、级联删除
- mysql外键级联删除
- 玩转MySQL的外键约束之级联删除篇
- mysql的外键约束级联修改和删除整理
- MySQL 外键约束和触发器,级联删除
- mysql外键级联更新删除
- Mysql外键级联动作(删除和更新)
- Mysql外键级联动作(删除和更新)
- mysql外键级联更新删除
- MYSQL_使用外键约束(constraint)或触发器(trigger)来进行级联更新、删除
- Hibernater由于外键设置不为空,导致在主键级联删除时失败解决办法!
- 级联删除设置外键方法
- mysql中外键约束级联更新与删除
- SQL外键级联更新、删除的设置
- [转]mysql如何设置主键和外键,实现级联更新、级联删除
- mysql 利用外键级联删除、更新
- MySQL入门(8)- 约束——主键约束&外键约束&级联更新/删除
- MySql 修改外键 支持级联删除
- MySQL外键及级联删除 && 表的存储引擎与创建索引 && 删除数据库和表
- 在创建外键约束的时候, 设置级联删除为SET NULL执行sql语句的时候显示有错误,(数据库为sqlserver2000)?