Вы можете применить это ограничение, используя индексированное представление:
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