Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

CONTROLLA Vincoli in SQL Server

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

  1. In Esplora oggetti , vai a una tabella richiesta.

  2. Fai clic con il pulsante destro del mouse sui Vincoli cartella e poi c fai clic su Nuovo vincolo...

  3. Nel riquadro destro di Verifica vincoli finestra di dialogo, fai clic su Espressione e quindi fare clic sul pulsante con i puntini di sospensione.

  1. 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:

  1. Il formato ZIP di base è composto da cinque cifre numeriche.

  2. Il numero di telefono americano standard è di dieci cifre, come (555) 555-1234

  3. 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.