Sql 检查两列上的约束

Sql 检查两列上的约束,sql,sql-server,check-constraints,Sql,Sql Server,Check Constraints,我想为Server2005的表添加一个检查约束,但无法解决它 MemberId ClubId MeetingId 1 100 10 2 100 10 3 100 10 7 101 10 <-This would throw a check constraint 1 100 11 2 100 11 我不想有一个以上的俱乐部竞购一个会议ID 基本上,ClubId只能

我想为Server2005的表添加一个检查约束,但无法解决它

MemberId ClubId MeetingId
1        100    10
2        100    10
3        100    10
7        101    10  <-This would throw a check constraint
1        100    11 
2        100    11  
我不想有一个以上的俱乐部竞购一个会议ID 基本上,ClubId只能属于一个MeetingId,但可以分配多个成员

如何实现这一点?

根据

编辑:尝试了代码并在@rippos comment之后修复了它

CREATE FUNCTION CheckFnctn()
RETURNS int
AS 
BEGIN
   DECLARE @retval int
   SELECT @retval = (select max(cnt) from (select COUNT(distinct ClubID) cnt FROM CheckTbl group by MeetingId) as t )
   RETURN @retval
END;
GO

ALTER TABLE CheckTbl ADD CONSTRAINT chkRowCount CHECK (dbo.CheckFnctn() <= 1 );
GO

在检查约束中使用函数是一种选择,但您可以创建一个函数来实现相同的约束

CREATE VIEW VIEW_UNIQUE_MEETINGID WITH SCHEMABINDING AS 
  SELECT  ClubID
          , MeetingID
          , COUNT_BIG(*)
  FROM    YourTable
  GROUP BY
          ClubID
          , MeetingID
GO

CREATE UNIQUE CLUSTERED INDEX UIX_VIEW_UNIQUE_MEETINGID ON VIEW_UNIQUE_CLUBID (MeetingID)

此表是否因性能原因而非规范化?MeetingID是FK吗?如果是,会议表中是否有ClubId列?如果是,ClubId不是特定会议的属性,而不是该与会者的属性吗?表?俱乐部Id的原因是因为这是一个旧的遗留系统,创建者决定基于这三个字段创建PK!丑陋的,但这是它的方式,有多大的麻烦,它将是正确的图式?一个缓慢但肯定的过程!我在路上,但是只需要添加一些约束,以确保数据在我之前清理干净!1但如果我的记忆力很好,如果你更新ClubId或MeetingID,这将失败。要解决这个问题,您应该将ClubID和MeetingID都传递给函数。我认为,在快照隔离的情况下,这也可能失败。请查找雨果·科内利斯或亚历克斯·库兹涅佐夫关于此的文章。@Lieven和@Martin感谢您的评论。我只做了临时谷歌搜索。我从来没有在praxis中使用过检查约束。似乎无法使其按预期工作。你是不是先自己试过的?@Rippo。哎呀,我试过了,然后修好了。我猜@Lieven和@martins注释仍然适用。由于名称“MemberMeetings”对模式绑定无效,因此出现错误无法对视图“view\u UNIQUE\u MEETINGID”进行模式绑定。@Rippo-您需要使用由两部分组成的名称来引用您的表,例如dbo.MemberMeetings,如果它在dbo模式中。Duh!谢谢@Lieven,这真的很好用。现在来了解它的工作原理:@Rippo,索引视图本质上是一个表,它是原始表的子集。子集仅包含ClubID&MeetingID计数。\u BIG仅在能够使用GROUP BY时才是必需的。在这个子集表中,MeetingID有一个唯一的约束。