2011-01-04 3 views
2

Je souhaite ajouter un Check Constraint à une table pour le serveur 2005, mais je n'arrive pas à le résoudre.Vérification de la contrainte sur deux colonnes

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 

Je ne veux pas avoir plus d'un ClubId pour un seul MeetingId Fondamentalement, un ClubId ne peut appartenir qu'à un seul MeetingId mais peut avoir plus d'un membre affecté.

Comment puis-je y parvenir?

+1

Cette table est-elle dénormalisée pour des raisons de performances? Est-ce que 'MeetingID' est un FK? Si oui, y a-t-il une colonne 'ClubId' dans la table de réunion? – outis

+1

Si tel est le cas, ClubId n'est-il pas un attribut d'une réunion particulière, plutôt qu'un attribut de cette table (Participants?)? –

+0

Raison du club Id est parce que c'est un ancien système où le créateur a décidé de créer un PK basé sur ces trois champs! Laide mais c'est comme ça – Rippo

Répondre

4

l'aide d'une fonction dans une contrainte de vérification est une option, mais vous pouvez créer un INDEXED VIEW qui fait la même restriction.

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) 
+0

+1 qui semble très élégante –

+0

Got erreur 'ne pouvez pas afficher bind de schéma « VIEW_UNIQUE_MEETINGID » parce que le nom « MemberMeetings » est invalide pour le schéma de liaison. ' – Rippo

+1

@Rippo - vous devez utiliser un nom en deux parties pour faire référence à votre table, par exemple 'dbo.MemberMeetings' s'il se trouve dans le schéma' dbo'. –

2

déduit de msdn

EDIT: essayé le code et fixe après @rippos commentaire

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 
+0

+1 mais si la mémoire me sert bien, cela échouera si vous mettez UPDATE' ClubId ou MeetingID. Pour résoudre ceci, vous devez passer à la fois ClubID et MeetingID à la fonction. –

+0

Cela peut également échouer sous l'isolement de capture instantanée, je pense. Cherchez des articles de Hugo Kornelis ou Alex Kuznetsov à ce sujet. –

+0

@Lieven et @Martin Merci pour les commentaires. J'ai seulement fait une recherche Google ad hoc. Je n'ai jamais utilisé de contraintes de vérification dans la praxis. –

Questions connexes