如何创建条件唯一约束

时间:2012-07-16 11:40:36

标签: sql sql-server sql-server-2005

有一个表格Table1,其中列Code接受nullables值,我们怎样才能确保这些值对于不可为空的值是唯一的,除了以'A'开头的代码可以是重复最多两次?

表1

Id |  Code
---------- 
1  |  NULL   --[ok]
2  |  A123   --[ok]
3  |  A123   --[ok]
4  |  B100   --[ok] 
5  |  C200   --[ok]
6  |  B100   --[not ok already used]
7  |  NULL   --[ok]

我试过创建一个索引视图,该解决方案适用于NULL值但不适用于我提到的第二种情况(跳过实际)

Create view v_Table_unq with schemabinding as( 
         select code from 
         dbo.Table1 
         where code is not null and code not like 'A%'
)
go
create unique clustered index unq_code on v_Table_unq(code)

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

表格创建

CREATE TABLE CheckConstraint
(
  Name VARCHAR(50),
)
GO

功能创建

create FUNCTION CheckDuplicateWithA() RETURNS INT AS BEGIN

  DECLARE @ret INT  =0 ;
  SELECT @ret = IsNull(COUNT(Name), 0) FROM CheckConstraint WHERE Name like '[A]%' group by Name having COUNT(name) >= 1;
  RETURN IsNUll(@ret, 0);
END;

GO

create FUNCTION CheckDuplicateOtherThenA() RETURNS INT AS BEGIN

  DECLARE @ret INT  =0 ;
  SELECT @ret = IsNull(COUNT(Name), 0) FROM CheckConstraint WHERE Name not like '[A]%' group by Name having COUNT(name) >= 1;
  RETURN IsNUll(@ret, 0);
END;

GO

约束

alter TABLE CheckConstraint
  add CONSTRAINT CheckDuplicateContraintWithA CHECK (NOT (dbo.CheckDuplicateWithA() > 2));
go

alter TABLE CheckConstraint
  add CONSTRAINT CheckDuplicateConmstraintOtherThenA CHECK (NOT (dbo.CheckDuplicateOtherThenA() > 1));
go

结果集

insert into CheckConstraint(Name)Values('b')  -- Passed
insert into CheckConstraint(Name)Values('b')  -- Failed

insert into CheckConstraint(Name)Values('a')  -- Passed
insert into CheckConstraint(Name)Values('a')  -- Passed
insert into CheckConstraint(Name)Values('a')  -- Failed

答案 1 :(得分:-1)

为什么你想要一个独特的约束?为什么不能在proc中添加这个逻辑,在表中插入数据?如果你没有单点插入/更新等?为什么不能把它放在触发器之后或之后?这样会更好,因为你可以处理很好,并且可以返回正确的错误消息。这将比具有索引视图的开销更少,这将增加开销。如果您需要对不以'A'开头的记录的唯一约束,那么您可以拥有一个持久列并且具有对此的独特限制。

当然你会有持有带索引的计算列的开销。但是如果你只需要唯一的contsraint就可以使用它。对于以'A'开头的值,这可能是一个空值。