2013-10-29 2 views
5

Ich habe eine Tabelle, die eine Multi-zu-Eins-Beziehung beschreibt, sagen wir zwischen Bildern und Alben. Ich möchte in der Lage sein, ein und nur ein Bild pro Album als Titelbild des Albums auszuwählen. Im Moment ist die Tabelle wie folgt aus:Wie erzwinge "Eindeutigkeit" mit booleschen Spalte (ein bisschen wie Radio-Buttons)?

AlbumID int primary key, 
PictureID int, 
IsCover bool 

Angenommen, ich will nicht das gesamte Schema ändern (eine Lösung könnte sein, die sich zu bewegen „ist Cover von“ Beziehung zu einer anderen Tabelle, die einen Ein- to-one-Beziehung, aber es ist bevorzugt, die bereits implementierten Abfragen nicht durch Hinzufügen einer anderen Tabelle zu ändern), gibt es eine Möglichkeit, zu erzwingen, dass alle Einträge mit derselben AlbumID ABER ONE IsCover auf false gesetzt haben?

Ich suche nach serverseitigen Lösungen. Ich arbeite mit Microsoft SQL Server 2012. Die UNIQUE-Einschränkung kann hier nicht angewendet werden, sonst könnte ich nur ein Cover und ein Cover für jedes Album haben. Ich habe bereits eine Überprüfung in meiner Anwendung implementiert, aber ich hätte gerne eine zusätzliche Sicherheitsstufe.

Vielen Dank im Voraus.

+2

Was ein Trigger nach Aktualisierung/nach Einsatz zu verwenden, ob der neue Eintrag überprüft soll die Abdeckung Einzelteil sein und dann alle anderen Marken relevante Einträge als falsch? –

+1

Mit der CHECK-Einschränkung können Sie beliebige Regeln in der Tabelle erzwingen. Erstellen Sie eine Funktion, die die tatsächliche Überprüfung durchführt, und verwenden Sie sie in der Integritätsbedingung. –

+0

Danke an euch beide! Ich versuche jedoch herauszufinden, ob es etwas Ähnliches wie die einzigartige Einschränkung gibt, um die Dinge so einfach wie möglich zu halten. – Simone

Antwort

4

Wahrscheinlich einzigartig gefilterten Index ist das, was Sie können helfen:

create table AlbumPics (
    AlbumID int not NULL, 
    PictureID int not NULL, 
    IsCover bit not NULL, 
    primary key clustered (AlbumID, PictureID) 
) 

create unique index UX_AlbumPics_CoverPic 
    on AlbumPics (AlbumID) where IsCover = 1 

-- insert 3 pics for album 1, one of them is cover pic 
insert into AlbumPics values 
(1, 1, 0), (1, 2, 1), (1, 3, 0) 

-- try to insert one more cover for album 1 - will fail 
insert into AlbumPics values 
(1, 4, 1) 
+1

+1, aber denken Sie daran, dass "gefilterte Indizes" SQL Server 2008 und höher sind. http://technet.microsoft.com/en-us/library/cc280372.aspx –

+0

Dank i-one, das ist genau die Lösung, die ich gesucht habe! Nur noch eine Sache: Wie kann ich sicherstellen, dass es immer ein Cover für ein Album gibt? Der obige Code stellt sicher, dass es nur einen gibt, aber es könnte auch keinen geben. – Simone

+1

@Simone, abgesehen davon, dass ich die Spalte 'CoverPictureID int not NULL' in die' Albums'-Tabelle aufgenommen habe, bin ich mir nicht sicher, ob es eine zuverlässige Möglichkeit gibt, jedes Album zu erzwingen. Wenn Sie das Tabellenschema "Alben" nicht ändern können, würde ich versuchen, es beim Datenabruf zu gewährleisten, z. B. das spezielle Bild "Kein Cover" auswählen, wenn es kein Cover für ein Album gibt oder einfach weglassen. " schmutzige Daten "Alben. –