在2列和第三列的组合之间定义唯一约束

时间:2018-09-10 14:07:29

标签: sql sql-server tsql

在下表中,(colA,colB,colC)是主键。在colD中,我定义了一种新的id类型,它对于(colA,colB)组合是唯一的,即:

colD = f(colA,colB)

,以便(A,1)应该给我id_1,(B,2)对应于id_2等,其中id是整数值。下表显示了一个错误,其中(A,1)有两个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 |
 | .   |  .   |  .   |  .   |
 | .   |  .   |  .   |  .   |
 | .   |  .   |  .   |  .   |
 |     |      |      |      |
 |     |      |      |      |
 |     |      |      |      |
 |     |      |      |      |

1 个答案:

答案 0 :(得分:1)

您可以使用索引视图强制执行此约束:

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_TIX_DRI_T选择更好的名称。例如。 IX_DRI_T_colD_mismatch_colA_colB