当前位置: 代码迷 >> SQL >> SQL SERVER增添约束限制序列
  详细解决方案

SQL SERVER增添约束限制序列

热度:38   发布时间:2016-05-05 11:30:14.0
SQL SERVER添加约束限制序列

SQL SERVER添加约束限制序列

         针对这样的要求,对一个项目提交采购单,要创建一个采购单的表。这个表至少包含以下字段:项目编号、采购单序号、其他相关内容。我们制定以下规则:针对其中的一个项目编号,插入或者修改的行的采购单序号必须从1,2,3开始的自然数。

         也就是说,如下表是合格的:

项目编号

    采购单序号    

                                      H213015B                                     

1

H213015B

2

H213015B

3

H213015B

4

H213016B

1

H213016B

2

         项目号H213015B的采购单号必须是从1开始,且按顺序增加;不可中间跳过;新插入项目号后,采购单序号又从新从1开始计数。如果在该表中插入(H213015B,6)数据库应该拒绝插入。

         从以上可以看出,项目编号和采购单序号一起可以组成该表的键来唯一确定某一行。

         可以使用很多方法达到这样的要求:锁,触发器,约束,外部程序控制等等。

         我们可以选择约束来完成这样的工作,原因是:锁、触发器会额外增加性能开销;不采用外部程序控制的原因是,我们希望数据库的完整性由数据库本身来控制,而不是借助于外部程序来完成,这样做的好处是保障了多用户之间的操作可能导致规则的打破。

         第一步,创建表:

         CREATE TABLE Temp_Sheet(Project_Number nchar(10) NOT NULL,Purchasing_ID int NOT NULL,PRIMARY KEY(Project_Number,Purchasing_ID))

创建表的时候,将Project_Number,Purchasing_ID作为键来标志某一特定的行,这么做也合符逻辑:一个订单就应该有它的标志。

         第二部,添加约束所需要的验证函数:

         

CREATE FUNCTION Check_Number2(@Project_Number_Inserted AS nchar(10),@Puchasing_ID_Inserted AS int)RETURNS bitASBEGIN   DECLARE @result bit=0   DECLARE @ID int=NULL   SELECT @ID=Purchasing_ID FROM(SELECT TOP 3 *,ROW_NUMBER() OVER(ORDER BY Purchasing_ID DESC) AS rn FROM dbo.Temp_Sheet WHERE [email protected]_Number_Inserted AND Purchasing_ID <= @Puchasing_ID_Inserted) tb WHERE rn=2;   IF (@IDISNOTNULL AND @[email protected]+1)--如果不为空且值增加了1      SET @result=1   ELSE      BEGIN         SELECT TOP 1 @ID=Purchasing_ID FROM dbo.Temp_Sheet WHERE [email protected]_Number_Inserted;--如果为空且值为1         IF(@[email protected]_ID_Inserted AND @Puchasing_ID_Inserted=1)            SET @result=1      END   RETURN @resultEND
这里编写了一个函数,根据函数传入的参数来确定插入的行是否合格。

第一个SELECT语句针对一个项目号已经有订单了,在该订单上面增加新的订单;或者UPDATE操作所做的约束。

第二个SELECT语句针对一个项目号还没有任何订单所做的约束:要添加订单必须从1开始。

         第三步,添加约束:

         ALTER TABLE dbo.Temp_SheetADD CONSTRAINT CK_Puchasing_ID_BY_Project_NumberCHECK (dbo.Check_Number2(Project_Number,Purchasing_ID)=1);

约束所执行的过程:

如果对上述代码能够看懂,我相信你已经知晓在插入已经更新表的时候,一个约束所执行的过程。

那么,根据我个人的理解,一条INSERT,UPDATE,SELECT语句都是作为一个事务来处理,也就是说,要么所有数据插入成功,要么所有数据没有插入成功,不存在只更新或者只插入了一部分数据。

因此该约束所执行的过程为:

1、设置一个起始点A;

2、不管三七二十一,将数据更新或者插入到当前表中;

3、执行键检查,如果有重复的键,则回滚至A,本事务处理结束,如果键检查合格,进入下一步;

4、执行约束处理,如果不满足约束要求,回滚至A;如果满足约束处理,进入下一步;

5、处理触发器等等;

6、完成更新及其插入操作。

根据以上过程,因此我们应该在约束处理函数中这样认为:进入到约束函数执行过程中,可以人为该更新的已经更新了;该插入的已经插入了。因此,在写约束函数时,要认为表已经较UPDATE,INSERT之前的语句不一样。

  以上仅为我的理解,如有不同,希望批评指正。

  相关解决方案