5

Prendere la seguente tabella di esempio:vincolo CHECK - permettono una sola colonna per essere vero se un'altra colonna è vero

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

Come si potrebbe riscrivere la cui sopra per includere vincoli di controllo come segue:

  • forza [RequireAdmin] di essere false se [RequireLogin] è false (cioè permettono solo di essere [RequireAdmin]vero se [RequireLogin] è Vero pur consentendo [RequireLogin] essere Vero e [RequireAdmin] di essere False
  • consentono solo [HideIfLoggedIn] di essere Vero se [RequireLogin] è False dichiarazioni caso nidificate
+0

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

risposta

6

In genere fare a il controllo per far funzionare quel tipo di logica. Ricordate che un caso in un controllo deve essere ancora una valutazione, quindi sarebbe prendere la forma

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

Guardando oltre le vostre esigenze tuttavia sembra che questo sarebbe anche lavorare ed è probabilmente più facile da leggere:

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

Doveva cambiare l'ultimo a '((RequireLogin = 1 AND HideIfLoggedIn = 0) OR (RequireLogin = 0 AND HideIfLoggedIn = 1) OR (RequireLogin = 0 AND HideIfLoggedIn = 0))' - ma sì, funziona benissimo - evviva – HeavenCore

+0

Bene, questa logica combinata booleana è sempre facile da ottenere indietro. – RThomas

2

Se ho l'algebra corretto:

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')) ; 

noti che questi vincoli di controllo sono definiti a livello di tabella non livello di colonna, come devono perché riferimento colum multipla ns. La risposta di RThomas non è valida Transact-SQL per questo motivo!

+0

Suggerisco due cose: (1) tentare di non applicare i vincoli usando 'NOT' - inverte semplicemente il modo in cui devi elaborare le cose mentalmente (2) usando 0 e 1 invece di stringhe di tipo booleano per i confronti BIT. –

+0

Non sono d'accordo con te su entrambi, Aaron. In primo luogo, le politiche organizzative sono generalmente espresse come negativi (ad esempio "i dipendenti non sono autorizzati a navigare su eBay durante le ore di lavoro"), quindi la creazione dei vincoli utilizzando la stessa formulazione offre una migliore comprensione della lettura. In secondo luogo, questi sono booleani: sono solo un campo di bit perché MSSQL non ha un tipo di dati booleani. Usare "vero" è meglio per la comprensione della lettura, perché esprime esplicitamente "vero" al lettore. Al contrario, 0 e 1 richiedono al lettore di ricordare se 0 rappresenta falso o vero in questa particolare lingua. –

+3

Beh, fai quello che vuoi, ovviamente. Posso dirti da 16 anni di esperienza in SQL Server che le due cose che ho menzionato * saranno confuse per la maggior parte degli utenti, indipendentemente da quanto senso potrebbero avere per te. –

Problemi correlati