在下表中,(colA, colB, colC( 是主键。在 colD 中,我定义了一种新的 id 类型,它在每个 (colA,colB( 组合中是唯一的,即:
colD = f(colA,colB(
所以 (A,1( 应该给我id_1,(B,2( 对应于 id_2 等,其中 id 是整数值。下表显示了一个错误,其中 (A,1( 有 2 个 ID - id_1 和 id_2。
我想强制实施一个约束,即每对值 (colA,colB( 映射到 colD 中的一个且只有一个值。当然,我可以向 (colA,colB,colC,colD( 添加一个唯一的约束,因为 (colA,colB,colC( 是主键,但这不会检测到 colC 和 colD 同时变化。
我不确定这里最好的方法是什么。
+colA + colB + colC + colD +
+--------------------------+
| A | 1 |180901| id_1 |
| A | 1 |180902| id_1 |
| A | 1 |180903| id_1 |
| A | 1 |180904| id_2 |
| . | . | . | . |
| . | . | . | . |
| . | . | . | . |
| | | | |
| | | | |
| | | | |
| | | | |
您可以使用索引视图强制实施此约束:
create table dbo.T (colA char(1) not null, colB int not null,
colC int not null, colD varchar(6) not null,
constraint PK_T PRIMARY KEY (colA,colB,colC))
go
create view dbo.DRI_T
with schemabinding
as
select colA,colB,colD,COUNT_BIG(*) as Cnt
from dbo.T
group by colA,colB,colD
go
create unique clustered index IX_DRI_T on dbo.DRI_T (colA,colB)
go
insert into T(colA,colB,colC,colD)
values ('A',1,180901,'id_1')
go
insert into T(colA,colB,colC,colD)
values ('A',1,180902,'id_1')
go
insert into T(colA,colB,colC,colD)
values ('A',1,180903,'id_1')
go
insert into T(colA,colB,colC,colD)
values ('A',1,180904,'id_2')
go
第四个插入语句生成的错误是:
Msg 2601, Level 14, State 1, Line 23
Cannot insert duplicate key row in object 'dbo.DRI_T' with unique index 'IX_DRI_T'. The duplicate key value is (A, 1).
The statement has been terminated.
希望您可以看到它是如何解决此错误的。当然,它的报告与直接约束违规并不完全相同,但我认为它包含足够的信息,我很乐意在我的一个数据库中使用它。
当然,如果您想使错误更明显,您可以为DRI_T
和IX_DRI_T
选择更好的名称。 例如IX_DRI_T_colD_mismatch_colA_colB