SQL约束验证唯一值

时间:2018-05-04 19:11:53

标签: sql sql-server sql-server-2008 constraints

我有一个表,我需要限制插入的数据,我已经使用了一个触发器,但我想知道我是否可以使用约束执行相同的任务。

字段是:

Id
Date
Passport
...
Deleted

约束必须允许 n 记录,而已删除字段 1 ,但如果已删除字段为 0 必须只有一行具有相同的日期和护照。

应该适用于此步骤:

  1. 添加Id = 1,Date = 2018-05-01,Passport = MPEUIE80,Deleted = 0
  2. 的行
  3. 删除Id = 1的行,因此“已删除”字段将为1
  4. 添加Id = 2的行,日期= 2018-05-01,Passport = MPEUIE80,已删除= 0
  5. 删除Id = 2的行,因此“已删除”字段将为1
  6. 添加Id = 3,Date = 2018-05-01,Passport = MPEUIE80,Deleted = 0
  7. 的行
  8. 添加Id = 4,Date = 2018-05-01,Passport = MPEUIE80,Deleted = 0
  9. 的行

    直到第五步,一切正常,但在最后一步必须有一个错误,那是因为我无法处理两行具有相同的日期,相同的 Passport < / strong>以及已删除 = 0

    提前致谢。

1 个答案:

答案 0 :(得分:25)

您可以使用过滤的唯一索引:

create table [t](
    [id] [int] NULL,
    [date] [datetime] NULL,
    [passport] [char](8) NULL,
    [deleted] [int] NULL
)

create unique index unq_t_date_passport on t(date, passport)
    where deleted = 0;

编辑:

如果筛选的索引不适用于您的SQL Server版本,那么您可能需要检查compatibility level。只要兼容性设置为100或更高,它就应该可用。您可以使用以下方法检查服务器版本和兼容级别:

SELECT SERVERPROPERTY('ProductVersion');
SELECT name, compatibility_level FROM sys.databases;

还有另一种方法可以在SQL Server 2005中启动,假设id是唯一且非负的。它使用计算列与过滤后的索引基本相同:

alter table t
    add column deleted_id (case when deleted = 0 then -1 else id end) persisted;

create unique index unq_t_passport_date_deleted_id on t(passport, date, deleted_id);