Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL Server条件唯一索引_Sql_Sql Server_Tsql_Azure Sql Database_Unique Constraint - Fatal编程技术网

SQL Server条件唯一索引

SQL Server条件唯一索引,sql,sql-server,tsql,azure-sql-database,unique-constraint,Sql,Sql Server,Tsql,Azure Sql Database,Unique Constraint,给出下表(和样本数据): 假设集合属于客户,我可以拥有一个唯一索引来约束标题在客户机中唯一,但同一集合中的同级标题除外 例如,我可以在两个客户机中设置标题1,但在一个客户机中不能设置两次。现在,对于Client1,我想要第二条记录的标题为Title1,但只有当它与所有其他标题为Title的记录具有相同的SetID 需要注意的是,我使用的是SQLAzure,但我也更感兴趣(例如2008 R2/2012) 编辑: 请注意,我无法更改表的结构。它已经以这种方式存在,并且背后有一个复杂的业务层。如果我能

给出下表(和样本数据):

假设
集合
属于
客户
,我可以拥有一个唯一索引来约束标题在客户机中唯一,但同一集合中的同级标题除外

例如,我可以在两个
客户机中设置
标题1
,但在一个
客户机中不能设置两次。现在,对于
Client1
,我想要第二条记录的标题为
Title1
,但只有当它与所有其他标题为
Title
的记录具有相同的
SetID

需要注意的是,我使用的是SQLAzure,但我也更感兴趣(例如2008 R2/2012)

编辑:

请注意,我无法更改表的结构。它已经以这种方式存在,并且背后有一个复杂的业务层。如果我能按原样修复这个问题,那就太好了,如果不能,那我就可以把它弄坏。

如果我答对了问题,我会在
SetID
Title
之间添加另一个表,它们之间有
1:1
关系,并在
ClientID和SetID
上添加一个唯一的索引

CREATE UNIQUE INDEX [Index_Name]
ON [dbo].[MyTable]([ClientID ], [SetID])

添加一个执行检查并在违反规则时引发失败异常的on insert/update触发器如何。
您可以在不更改数据模型的情况下添加这些视图。

您可以尝试其他索引视图

例如,表:

create table dbo.Test (PK int, ClientID int, SetID int, Title varchar(50), primary key (PK))

insert into dbo.Test values
    (1, 1, 1, 'Title1')
    ,(2, 1, 1, 'Title1')
    ,(3, 2, 2, 'Title1')
    ,(4, 2, 2, 'Title1')
    ,(5, 1, 3, 'Title2')
    ,(6, 1, 3, 'Title2')
视图和索引:

create view dbo.vTest
with schemabinding
as
    select ClientID, Title, SetID, cnt=count_big(*)
    from dbo.Test
    group by ClientID, Title, SetID
GO
create unique clustered index UX_vTest on dbo.vTest (ClientID, Title)
GO
然后:


谢谢你的建议。我同意这将是一个更好的设置,但不幸的是,我没有改变结构的选择。我的选项是:添加列(计算?)、添加索引、视图等。我看不出您将如何拥有三列的唯一索引,以允许有重复的信息。我想只有当您添加例如identity列作为索引的一部分时,才能解决这个问题,但不允许更改表。我可以添加列,但不能进行侵入性更改,例如将表拆分为两个。@gotqn。它不必是唯一的索引,这正是我认为可以实现的,只是还没有弄清楚如何实现!:)不,您将无法在该场景中创建唯一索引,因为规则允许重复。你需要在触发器或应用程序的数据层中强制执行。我考虑过这一点,但感觉有点脏。我使用了一个插入后DML触发器来实现一个真正需要插入前的目的。我关心的是使用触发器来实现这一点的性能。你能提供优点和缺点吗?如果你能使用触发器,你可以创建
而不是INSERT
触发器来处理INSERT并进行检查。@gotgn。谢谢,我知道这一点,但是一个代替触发器要求我重写可能发生的插入。如果我能在[table]中插入[SELECT*FROM INSERTED
,我会很高兴,但我不能在身份上这样做。这是我考虑最多的路线。谢谢你抽出时间。
create view dbo.vTest
with schemabinding
as
    select ClientID, Title, SetID, cnt=count_big(*)
    from dbo.Test
    group by ClientID, Title, SetID
GO
create unique clustered index UX_vTest on dbo.vTest (ClientID, Title)
GO
insert into dbo.Test values (7, 1, 1, 'Title1') -- will pass
insert into dbo.Test values (8, 1, 1, 'Title1') -- will pass
insert into dbo.Test values (9, 1, 2, 'Title1') -- will fail
insert into dbo.Test values (10, 2, 2, 'Title1') -- will pass
insert into dbo.Test values (11, 1, 3, 'Title1') -- will fail