0

有一个表:Table1其中一列Code接受可为空值我们如何确保值对于不可为空的值是唯一的,除了开头的代码'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)

感谢帮助

4

2 回答 2

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
于 2012-07-16T18:54:07.103 回答
-1

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

当然,您将有使用索引持久化计算列的开销。但是如果您只需要唯一的约束,您可以使用它。对于以“A”开头的值,这可能是一个空值。

于 2012-07-16T11:52:15.493 回答