SQL约束验证唯一值

Wlt*_*Rpo 17 sql sql-server constraints sql-server-2008

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

这些领域是:

Id
Date
Passport
...
Deleted
Run Code Online (Sandbox Code Playgroud)

当Deleted字段为1时,约束必须允许n条记录,但如果Deleted字段为0,则必须只有一条具有相同Date和Passport的行.

应该为这个步骤工作:

  1. 添加Id = 1,Date = 2018-05-01,Passport = MPEUIE80,Deleted = 0的行
  2. 删除Id = 1的行,因此Deleted字段将为1
  3. 添加Id = 2,Date = 2018-05-01,Passport = MPEUIE80,Deleted = 0的行
  4. 删除Id = 2的行,因此Deleted字段将为1
  5. 添加Id = 3,Date = 2018-05-01,Passport = MPEUIE80,Deleted = 0的行
  6. 添加Id = 4,Date = 2018-05-01,Passport = MPEUIE80,Deleted = 0的行

直到第五步,一切正常,但在最后一步必须有一个错误,那是因为我无法处理具有相同Date,同一Passport和Deleted = 0的两行

提前致谢.

Gor*_*off 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;
Run Code Online (Sandbox Code Playgroud)

编辑:

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

SELECT SERVERPROPERTY('ProductVersion');
SELECT name, compatibility_level FROM sys.databases;
Run Code Online (Sandbox Code Playgroud)

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

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);
Run Code Online (Sandbox Code Playgroud)

  • @WltrRpo...过滤的索引在SQL Server 2008中引入(https://docs.microsoft.com/en-us/sql/t-sql/statements/create-index-transact-sql?view=sql-server-2017#syntax).如果它们不适合您,可能您的兼容级别设置为某些早期版本(https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql -compatibility级别?视图= SQL服务器-2017). (6认同)