zoukankan      html  css  js  c++  java
  • 关于数据的级联删除和更新

    很多时候,我们会碰到这样的场景:“删除一个表的数据的时候,将另一个表的相关数据删除。

    在这里我建立两张表:“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]

    创建后的表大致如下:

    B6BCCB218C4946999A038748EDD3169C

    D2AA9CB97D5E4921BF534E512CC55C88

    一些实验数据:

    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 表中建立外键约束,

    41CAF4CCE0594D539B8FE9DFF831BC31

    看到删除规则了吗,指定为层叠的话,那么当删除ProductCategory的时候,就会删除Product了。

    
    
    select * from ProductCategory;
    select * from product;
    
    Delete from ProductCategory;
    
    select * from ProductCategory;
    select * from product;

    结果如下:

    8DD435ED59A34A0EB60B4D7AC9A81A07

    作者:LoveJenny
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
     
     
  • 相关阅读:
    进制
    流程控制
    运算符
    格式化输出
    数据结构-树的遍历
    A1004 Counting Leaves (30分)
    A1106 Lowest Price in Supply Chain (25分)
    A1094 The Largest Generation (25分)
    A1090 Highest Price in Supply Chain (25分)
    A1079 Total Sales of Supply Chain (25分)
  • 原文地址:https://www.cnblogs.com/chuhj/p/9009288.html
Copyright © 2011-2022 走看看