. 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;
結果如下: