1. 程式人生 > >關於數據的級聯刪除和更新

關於數據的級聯刪除和更新

TP table 資料 clu 通過 兩張 之間 microsoft 關聯

很多時候,我們會碰到這樣的場景:“刪除一個表的數據的時候,將另一個表的相關數據刪除。

在這裏我建立兩張表:“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;

結果如下:

技術分享圖片

關於數據的級聯刪除和更新