【问题标题】:Looking for suggestions on what table constraints to have to achieve uniqueness寻找有关必须实现唯一性的表约束的建议
【发布时间】:2017-12-13 08:19:44
【问题描述】:

在 sql-server 表中期望如下数据:

具有 id1 的资源将用于不同版本的条目,并且对于不同版本也可以具有不同的名称。

但是名称不能在资源之间共享。一旦 id1 使用 NameX,其他资源应该不能使用相同的名称。

请建议我可以定义的 sql-table 约束来实现这一点:

标识名称版本 ------------------ id1 名称1 1 id1 名称1 2 id1 名称A 3 id1 名称 X 4 id2 名称2 1 id2 NameX 2 -- 无效记录,NameX 已用于 id1

【问题讨论】:

  • 您使用的是 MySQL 还是 MS SQL Server?不要标记未涉及的产品。

标签: sql sql-server unique-constraint


【解决方案1】:

您可以使用带有几个唯一索引的索引视图,以确保每个名称在视图中的每个 id 值仅出现一次,然后使完整的名称集唯一:

create table dbo.Ix (ID varchar(20) not null, Name varchar(20) not null, 
                     Version int not null)
go
create view dbo.DRI_Ix_Unique_Names
with schemabinding
as
    select
        Id,Name,COUNT_BIG(*) as Cnt
    from
        dbo.Ix
    group by
        ID,Name
go
create unique clustered index IX_DRI_IX_Unique_Names on dbo.DRI_Ix_Unique_Names (Id,Name)
go
create unique nonclustered index IX_DRI_IX_Unique_Names_Only on 
        dbo.DRI_Ix_Unique_Names(Name)
go
insert into dbo.Ix(ID,Name,Version) values
('id1','Name1',1)
go
insert into dbo.Ix(ID,Name,Version) values
('id1','Name1',2)
go
insert into dbo.Ix(ID,Name,Version) values
('id1','NameA',3)
go
insert into dbo.Ix(ID,Name,Version) values
('id1','NameX',4)
go
insert into dbo.Ix(ID,Name,Version) values
('id2','Name2',1)
go
insert into dbo.Ix(ID,Name,Version) values
('id2','NameX',2)

这会导致 5 次成功插入,然后出现错误,因为最后一次插入违反了非聚集唯一索引。

我不确定版本列如何影响您的要求,并且没有在任何约束中使用它。

【讨论】:

  • 嗨,Damien,这里的诀窍是视图本身是阻止插入基础表的原因(我正在努力学习)?
  • @TimBiegeleisen - 是的。我通常在这样的视图前面加上名称“DRI”,以清楚地表明该视图是出于参照完整性的原因而引入的,而不是(必然)对查询本身有用。
  • 感谢@Damien_The_Unbeliever!!!我们将尝试这种方法。如果遇到任何问题会更新。
【解决方案2】:

创建一个触发器,在插入新记录之前检查值是否存在,如果记录存在则抛出错误

喜欢这个

CREATE TRIGGER ti_CheckRecord
on YourTable before insert
begin

if exists(select 1 from inserted where exists(select 1 from yourtable where name = inserted.name and id <> inserted.id))
begin
 --write your error code here
end

end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 2017-02-15
    • 1970-01-01
    • 2018-02-02
    • 2020-10-29
    相关资源
    最近更新 更多