假设一个业务规则规定某些情况不允许存在.并且不允许使用外键进行限制,此时Instead of 触发器可以作为备选答案,但是通常这类触发器在以后带来的麻烦会多于其带来的便利。还有一种解决方式是使用包含唯一索引的索引视图与只有一个两行的dummy table进行连接。
假设你有如下两个表,地区和办事处
Region表
RegionId |
RegionName |
IsActive |
EffectiveDate |
ExpirationDate |
1 |
East |
1 |
1/1/2009 |
NULL |
2 |
West |
1 |
1/1/2009 |
NULL |
3 |
North |
1 |
1/1/2009 |
NULL |
4 |
South |
1 |
1/1/2009 |
NULL |
5 |
Antarctica |
1 |
1/1/2009 |
NULL |
Office表
RegionId |
RegionId |
OfficeName |
IsActive |
EffectiveDate |
ExpirationDate |
1 |
1 |
New York |
1 |
1/1/2009 |
NULL |
2 |
2 |
Los Angeles |
1 |
1/1/2009 |
NULL |
3 |
3 |
Minneapolis |
1 |
1/1/2009 |
NULL |
4 |
4 |
Atlanta |
1 |
1/1/2009 |
NULL |
5 |
5 |
Byrd Station |
1 |
1/1/2009 |
NULL |
你如何保证活动的(IsActive=1)的Office只属于活动的Region?
上面提到的表需要某种参照完整性.RegionId是Office表的外键,Check约束保证了在ExpirationDate不为Null的情况下,永远不会是1.但是我们如何防止IsActive的的Office属于IsActive=0的Region呢?我们可以重新设计表或是使用Instead of触发器,但更方便的做法是使用一个含有唯一索引的索引视图与一个两行的哑表进行连接。
DuplicateRows table
DuplicateRows表包含两行,如下
DuplicateRowIndex |
DuplicateRowValue |
1 |
Duplicate Row |
2 |
Duplicate Row |
对于这个表的唯一要求是这个表至少含有两行,其结构和内容并不重要。这个表甚至也可以是只有一列的表并且每行的值不一样。而我这里用这种方式命名是因为“Duplicate Row”这个名字看起来不容易产生混淆,并且这样的命名也不会使得其它DBA删除这个表。