5

Nehmen Sie das folgende Beispiel-Tabelle:überprüfen Constraint - erlauben nur eine Spalte um wahr zu sein, wenn eine andere Spalte wahr ist

CREATE TABLE [dbo].[tbl_Example](
    [PageID] [int] IDENTITY(1,1) NOT NULL, 
    [RequireLogin] [bit] NOT NULL, 
    [RequireAdmin] [bit] NOT NULL, 
    [HideIfLoggedIn] [bit] NOT NULL 
) 

Wie würde man die oben umschreiben Check-Einschränkungen umfassen wie folgt:

  • [RequireAdmin] Kraft Falsch wenn [RequireLogin] ist Falsch (dh nur erlauben [RequireAdmin]Wahr wenn 0 zu seinist Wahre während [RequireLogin] ermöglicht Wahre und [RequireAdmin] zu sein Falsch
  • werden nur erlauben [HideIfLoggedIn]Wahre wenn [RequireLogin] ist Falsch
+0

(1) [RequireAdmin] <= [RequireLogin]? (2) [RequireLogin] = 0 ODER [HideIfLoggedIn] = 1? – wqw

Antwort

6

Sie normalerweise tun verschachtelten case-Anweisungen werden in die Überprüfung, damit diese Art von Logik funktioniert. Denken Sie daran, dass ein Fall in einer Kontrolle noch eine Auswertung sein müssen, so wäre es

CHECK (case when <exp> then 1 end = 1). 

Mit Blick auf Ihre genauen Anforderungen an die Form jedoch scheint es, dass dies auch funktionieren würde und ist wahrscheinlich einfacher zu lesen:

CREATE TABLE [dbo].[tbl_Example] 
(
    [PageID] [int] IDENTITY(1,1) NOT NULL, 
    [RequireLogin] [bit] NOT NULL, 
    [RequireAdmin] [bit] NOT NULL, 
    [HideIfLoggedIn] [bit] NOT NULL 
) 

ALTER TABLE [dbo].[tbl_Example] ADD CONSTRAINT 
    [RequireAdmin] CHECK 
     ((RequireAdmin = RequireLogin) OR 
     (RequireLogin=1)); 

ALTER TABLE [dbo].[tbl_Example] ADD CONSTRAINT 
     [HideIfLoggedIn] CHECK 
     ((RequireLogin=1 AND HideIfLoggedIn=0) OR 
     (RequireLogin=0 AND HideIfLoggedIn=1) OR 
     (RequireLogin=0 AND HideIfLoggedIn=0)) 
+1

Hatte die letzte Änderung in '((RequireLogin = 1 UND HideIfLoggedIn = 0) ODER (RequireLogin = 0 UND HideIfLoggedIn = 1) ODER (RequireLogin = 0 UND HideIfLoggedIn = 0))' - aber ja, funktioniert super - Prost – HeavenCore

+0

Gut, diese kombinierte boolesche Logik ist immer leicht rückwärts zu finden. – RThomas

2

Wenn ich die Algebra richtig:

alter table dbo.Example 
add constraint RequireAdmin_RequireLogin_ck 
check (not (RequireAdmin = 'true' and RequireLogin = 'false')) ; 
alter table dbo.Example 
add constraint HideIfLoggedIn_RequireLogin_ck 
check (not (HideIfLoggedIn = 'true' and RequireLogin = 'true')) ; 

Beachten sie, dass diese Kontroll Einschränkungen auf Tabellenebene definiert sind, nicht die Spalte Ebene, wie sie müssen, weil sie mehrere colum Referenz ns. RThomas 'Antwort ist aus diesem Grund nicht gültig Transact-SQL!

+0

Ich empfehle zwei Dinge: (1) Versuchen Sie nicht, Beschränkungen mit 'NOT' zu erzwingen - es kehrt nur die Art zurück, wie Sie mental (2) mit 0 und 1 statt Booleschen String-Literalen für BIT-Vergleiche verfahren müssen. –

+0

Ich stimme nicht mit Ihnen beiden, Aaron. Erstens werden organisatorische Richtlinien in der Regel als Negativ ausgedrückt (z. B. "Angestellte dürfen während der Arbeitszeit nicht in ebay surfen"), so dass das Erstellen der Einschränkungen mit demselben Wortlaut zu einem besseren Leseverständnis führt. Zweitens sind dies boolesche Werte - sie sind nur ein kleines Feld, weil MSSQL keinen booleschen Datentyp hat. Die Verwendung von "wahr" ist besser für das Leseverstehen, weil es dem Leser "wahr" explizit vermittelt. Im Gegensatz dazu müssen 0 und 1 den Leser daran erinnern, ob 0 in dieser Sprache falsch oder wahr ist. –

+3

Tja, tu was du willst, natürlich. Ich kann Ihnen aus 16 Jahren Erfahrung in SQL Server sagen, dass die beiden Dinge, die ich erwähnt habe * verwirrend für die meisten Benutzer sein werden, unabhängig davon, wie viel Sinn sie Ihnen möglicherweise machen. –