In questo articolo parleremo dei vincoli CHECK. Vedremo come aggiungere i vincoli CHECK alle colonne della tabella di SQL Server e discuteremo le insidie che potresti incontrare quando utilizzi questo tipo di vincoli di SQL Server.
CONTROLLA le basi dei vincoli
I vincoli CHECK sono semplicemente istruzioni condizionali (predicati che restituiscono TRUE o FALSE) che fanno riferimento alle colonne della tabella per mantenere l'integrità dei dati. Quando si inseriscono dati in una colonna o in più colonne in una singola riga, entrano in azione i vincoli CHECK. Valutano i dati da inserire. Nel caso in cui i dati non soddisfino la condizione specificata nel vincolo CHECK, l'inserimento non riesce.
Considera il seguente esempio:
È necessario impostare una restrizione alla colonna Stipendio in modo che memorizzi solo valori positivi non superiori a $ 150.000. La dichiarazione condizionale avrà il seguente aspetto:(Stipendio>=0 e Stipendio <=150000). Durante il tentativo di inserire valori negativi, il predicato risulterà FALSE e l'inserimento avrà esito negativo.
È possibile aggiungere un vincolo CHECK a una o più colonne. L'aggiunta di un vincolo CHECK a più colonne può essere implementata a livello di tabella.
Utilizzo dei vincoli CHECK
Come creare vincoli CHECK in SSMS
In Esplora oggetti , vai a una tabella richiesta.
Fai clic con il pulsante destro del mouse sui Vincoli cartella e poi c fai clic su Nuovo vincolo...
Nel riquadro destro di Verifica vincoli finestra di dialogo, fai clic su Espressione e quindi fare clic sul pulsante con i puntini di sospensione.
Digita un'espressione di vincolo CHECK nel campo di testo di Verifica espressione di vincolo la finestra di dialogo. Ad esempio, per consentire solo codici postali a sette cifre in una colonna CAP, l'espressione può avere il seguente aspetto:
Nel Designer tavolo sezione, puoi impostare le regole per far rispettare il vincolo.
CONTROLLA Vincolo su CREATE TABLE
Considera il seguente esempio:
È necessario creare una tabella che memorizzi i dati sui clienti della banca e la riempia con i dati di prova. La tabella includerà le seguenti colonne:ID cliente, Nome, Cognome, Stato, Telefono, Città, Stato e CAP.
Durante lo sviluppo della tabella, dobbiamo prendere in considerazione i seguenti fatti:
Il formato ZIP di base è composto da cinque cifre numeriche.
Il numero di telefono americano standard è di dieci cifre, come (555) 555-1234
Le abbreviazioni di due lettere vengono utilizzate per rappresentare le divisioni politiche degli Stati Uniti per indirizzi postali, elaborazione dati, abbreviazioni generali e altri scopi.
Il compito è fornire la coerenza dei dati per la tabella. È necessario vietare l'inserimento di numeri di telefono a 12 cifre e zip a 6 cifre, ecc. Per fare ciò, SQL Server ci consente di aggiungere uno o più vincoli CHECK per ogni colonna della tabella.
Nella sezione precedente, abbiamo esaminato l'unico modo per creare un vincolo CHECK in SSMS. Ora discuteremo come creare il vincolo con l'aiuto di T-SQL.
Il seguente script mostra come creare un vincolo CHECK sulla colonna Zip:
CREATE TABLE Customers ( Customer_Id tinyint NOT NULL, [First Name] varchar(50), [Last Name] varchar(50), Status varchar(50), Phone tinyint, Address varchar(50), State varchar(50), Zip tinyint, Email varchar(50), [Credit Limit] INT NULL, CONSTRAINT CK_Zip CHECK (Zip LIKE REPLICATE ('[0-9]', 5)) --Check Constraint Condition )
Ora, vediamo cosa otteniamo quando proviamo a inserire un valore di 6 cifre nella colonna Zip:
INSERT INTO dbo.Customers (Customer_Id, [First Name], [Last Name], Status, Phone, Address, State, Zip, Email) SELECT 1, 'James', 'Madison', 'Mr', 555-555-1234, 'Madison street, 12', 'LA', 123456, NULL GO
L'inserimento non riesce e SQL Server mostra la seguente prevenzione:
Finora, tutto bene.
Espressione CASE nel vincolo CHECK
Supponiamo che la banca abbia una regola aziendale per fissare il limite di credito per i residenti dello stato della Louisiana a meno di $ 150.000. Implementeremo questo requisito aggiungendo un vincolo CHECK alla colonna Limite di credito:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Credit_Limit CHECK (State='LA' AND [Credit Limit] <= 150000) GO INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (1, 'James Black', 'Mr', 5558787, 'LA', 46853, '[email protected]', 120000); GO INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (2, 'Mark Spencer', 'Mr', 3332244, 'NY', 23487, '[email protected]', 200000); GO
Quando eseguiamo l'istruzione precedente, otteniamo il seguente errore:
L'istruzione INSERT era in conflitto con il vincolo CHECK. Cosa è andato storto?
Diamo un'occhiata più da vicino alla query. Si noti che il vincolo CHECK consente solo i valori "LA" per la colonna Stato. Allo stesso tempo, i valori nella colonna Credito non devono superare 150000.
Allo stesso modo, il vincolo CHECK non consentirebbe di scrivere altri codici di stato nella colonna.
Quindi, dobbiamo modificare la condizione. Secondo la logica aziendale, la banca fornisce $ 150000 del limite di credito per i residenti in Louisiana. Allo stesso tempo, questo valore può variare per gli altri residenti.
Per implementare questo caso, utilizzeremo la clausola CASE all'interno del vincolo CHECK:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Credit_Limit CHECK (CASE WHEN State='LA' AND [Credit Limit] <= 150000 THEN 1 ELSE 0 END = 1) GO
Questa espressione soddisfa pienamente la logica aziendale.
Valori NULL nel vincolo CHECK
La banca divide i suoi clienti in segmenti. La colonna Stato contiene i dati che determinano se un client è VIP o regolare. L'importo massimo del limite di credito per i clienti abituali è di $ 200.000. I VIP possono prelevare $ 500.000.
Il vincolo CHECK può apparire come segue:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Status_Credit_Limit CHECK (Status = 'VIP' OR Status = 'Regular') GO
Si noti che il vincolo CHECK consente di inserire NULL nella colonna Stato (a condizione che non vi sia alcun vincolo NOT NULL esplicitamente definito). Il vincolo CHECK valuta i valori e restituisce TRUE o FALSE. Valuta NULL come SCONOSCIUTO. Pertanto, i NULL non causeranno errori. Ciò è contrario ai predicati nelle clausole WHERE nelle istruzioni SELECT o UPDATE.
CHECK e NOCHECK
Di tanto in tanto, la logica aziendale cambia. Provoca modifiche agli oggetti del database. Immagina che un paese estenda la base del codice postale e aggiunga valori a 6 cifre.
I vecchi valori a 5 cifre non verranno più assegnati alle aree. Tuttavia, sono ancora validi per quelli esistenti. Pertanto, il vincolo CHECK deve tenere conto dei dati esistenti nel vecchio formato e convalidare i dati nel nuovo formato.
La clausola NOCHECK risolve questo problema:
ALTER TABLE Customers WITH NOCHECK ADD CONSTRAINT CK_Zip_Code CHECK (Zip LIKE REPLICATE('[0-9]', 6)); GO
Il seguente inserimento è riuscito:
INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (102, 'Jake Harrison', 'VIP', 555-555-1234, 'NY', 123456, '[email protected]', 100000); GO
Quando si tenta di inserire un zip a cinque cifre, il motore genera l'errore:
CONTROLLO VINCOLI DBCC
SQL Server fornisce DBCC CHECKCONSTRAINTS per cercare dati che non corrispondono ai vincoli.
Se c'è un problema di integrità del database, esegui DBCC CHECKCONSTRAINTS per l'intero database per assicurarti che non ci siano problemi.
Nota che questo comando influisce sulle prestazioni. Pertanto, non dovrebbe essere eseguito su base programmata.
È possibile eseguire DBCC CHECKCONSTRAINTS per un singolo vincolo, una tabella o l'intero database.
Rispetto ad altri comandi di controllo, DBCC CHECKCONSTRAINTS richiede molto tempo per essere completato e consuma risorse di sistema. A differenza di altri comandi, CHECKCONSTRAINTS non utilizza uno snapshot del database.
Conclusione
I vincoli CHECK forniscono il meccanismo per valutare i dati prima dell'inserimento. I vincoli CHECK possono fare riferimento a una singola colonna oa più colonne di tabella.
I vincoli sono semplicemente predicati che risultano TRUE, FALSE o UNKNOWN. Nel caso in cui NULL sia inserito in una tabella, un vincolo non viene violato.