如何使用索引视图和一个只有2行的表限制业务规则
作者:网络转载 发布时间:[ 2012/8/29 10:53:38 ] 推荐标签:
InvalidRegionIsInactiveButOfficeIsActiveView视图
业务规则是如果区域(Region)是不活动的,不能存在活动的办事处(Office)与其关联。换句话说,不能在属于某个区域的办事处还是active的情况下关闭这个区域,除非设置IsActive为0或是将这个办事处分到其它区域(Region),下面的View显示了显示了Region的IsActive为0并且属于它的offce的IsActive为1的例子。这违背了预设的业务规则.与dbo.DuplicateRows进行Cross Join是为了实现如果Where子句满足条件,少返回两行。
CREATE View dbo.InvalidRegionIsInactiveButOfficeIsActiveView With SchemaBinding
As
SELECT dbo.Region.RegionId
FROM dbo.Region
INNER JOIN dbo.Office
ON dbo.Region.RegionId = dbo.Office.RegionId
CROSS JOIN dbo.DuplicateRows
WHERE dbo.Region.IsActive = Convert(bit, 0)
AND dbo.Office.IsActive = Convert(bit, 1)
后的画龙点睛之笔是创建索引,索引是为了防止重复行,但是这个视图与一个两行的表进行Cross Join,这使得如果要返回结果,则返回一个两行的结果。但这又违背了索引,所以这种情况永远不可能发生。
CREATE UNIQUE CLUSTERED INDEX IX_RegionInvalidOfficeIsActiveView_RegionId ON dbo.InvalidRegionIsInactiveButOfficeIsActiveView
(RegionId ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
后的结果是不会违背业务规则。
测试:关闭Antarctica区域
总部的那帮家伙决定关闭Antarctica区域。下面语句在不顾与之关联的Office的状态的情况下设置Region的IsActive为0。
UPDATE dbo.Region
SET dbo.Region.IsActive = Convert(bit, 0),
dbo.Region.ExpirationDate = GetDate()
WHERE dbo.Region.RegionName = N'Antarctica'
当执行后,发生如下错误:
Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.InvalidRegionIsInactiveButOfficeIsActiveView' with unique index 'IX_RegionInvalidOfficeIsActiveView_RegionId'. The duplicate key value is (5).
在关闭Antarctica区域之前,Byrd Station办事处必须设置成不活动的或者是分配给其它区域,因为我并不想解雇这个办事处的任何人,所以我将这个办事处分为了其它区域。
UPDATE dbo.Office
SET dbo.Office.RegionId = (SELECT dbo.Region.Regionid
FROM dbo.Region
WHERE dbo.Region.RegionName = N'South'
)
FROM dbo.Office
WHERE dbo.Office.RegionId =(SELECT dbo.Region.Regionid
FROM dbo.Region
WHERE dbo.Region.RegionName = N'Antarctica'
)
一旦没有任何活动的办事处与Antarctica区域相关联,我可以通过Update语句来关闭Antarctica区域了。
如何在你的数据库中实现这个技巧
下面几部帮助你在数据库中实现这个技巧:
1、创建dbo.DuplicateRows table表并插入两条数据
2、写一个违反了业务规则并且还能返回结果的查询
3、在这个查询中与dbo.DuplicateRows进行Cross Join
4、创建一个包含SchemaBinding参数和上面查询语句的视图
5、在视图上创建索引
总结
使用索引视图和一个两行的表进行连接或许并不是实现业务规则有效的手段,但是使用了这种方法可以避免使用复杂的Instead of触发器。假如微软提供了“Before触发器”使得违反业务规则的查询在执行之前被取消的话,不需要我这种手段了。上面的技巧可以看作是一个无奈的人实现的山寨版”before 触发器”。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11