Condividi tramite


Vincoli CHECK

I vincoli CHECK assicurano l'integrità di dominio limitando i valori accettati da una colonna. Sono simili ai vincoli FOREIGN KEY perché controllano i valori inseriti in una colonna. La differenza consiste nel modo in cui vengono determinati i valori validi. I vincoli FOREIGN KEY ottengono l'elenco di valori validi da un'altra tabella e i vincoli CHECK determinano i valori validi da un'espressione logica che non si basa sui dati di un'altra colonna. Ad esempio, è possibile limitare l'intervallo di valori di una colonna salary creando un vincolo CHECK che consente solo dati compresi tra 15.000 e 100.000 euro. In questo modo si evita di inserire stipendi con valori non compresi nell'intervallo regolare.

È possibile creare un vincolo CHECK con qualsiasi espressione logica (booleana) che restituisce TRUE o FALSE in base agli operatori logici. Per l'esempio precedente, l'espressione logica è salary >= 15000 AND salary <= 100000.

È possibile applicare più vincoli CHECK a una colonna e inoltre applicare un singolo vincolo CHECK a più colonne creandolo a livello di tabella. Ad esempio, è possibile utilizzare un vincolo CHECK in più colonne per confermare che a ogni riga con un valore di colonna country/region pari a USA corrisponda un valore di due caratteri nella colonna state. In questo modo è possibile verificare più condizioni simultaneamente.

Nota di attenzioneAttenzione

I vincoli che prevedono la conversione implicita o esplicita di tipi di dati possono impedire l'esecuzione di operazioni specifiche. Ad esempio, i vincoli definiti nelle tabelle di origine per il cambio di partizione possono impedire l'esecuzione di un'operazione ALTER TABLE...SWITCH. Evitare la conversione di tipi di dati nelle definizioni dei vincoli.

Limitazioni per i vincoli CHECK

I vincoli CHECK non accettano i valori che restituiscono FALSE. I valori Null restituiscono UNKNOWN e pertanto se vengono inseriti in un'espressione è possibile che un vincolo venga ignorato. Si supponga, ad esempio, di inserire un vincolo su una colonna di tipo int denominata MyColumn e di specificare che MyColumn può contenere solo il valore 10 (MyColumn=10). Se si inserisce il valore NULL in MyColumn, Motore di database inserisce NULL e non restituisce un errore.

Un vincolo CHECK restituisce TRUE se la verifica della condizione controllata non restituisce FALSE per nessuna riga della tabella. Se una tabella appena creata non contiene righe, tutti i vincoli CHECK sulla tabella sono considerati validi. Questa situazione può generare risultati imprevisti, come è illustrato nell'esempio seguente.

CREATE TABLE CheckTbl (col1 int, col2 int);
GO
CREATE FUNCTION CheckFnctn()
RETURNS int
AS 
BEGIN
   DECLARE @retval int
   SELECT @retval = COUNT(*) FROM CheckTbl
   RETURN @retval
END;
GO
ALTER TABLE CheckTbl
ADD CONSTRAINT chkRowCount CHECK (dbo.CheckFnctn() >= 1 );
GO

Il vincolo CHECK inserito specifica che deve essere presente almeno una riga nella tabella CheckTbl. Poiché nella tabella non sono presenti righe per le quali è possibile verificare la condizione del vincolo, l'istruzione ALTER TABLE ha tuttavia esito positivo.

I vincoli CHECK non vengono convalidati durante l'esecuzione di istruzioni DELETE. L'esecuzione di istruzioni DELETE su tabelle che includono tipi di vincoli CHECK specifici può pertanto generare risultati imprevisti. Ad esempio, si considerino le istruzioni seguenti eseguite sulla tabella CheckTbl.

INSERT INTO CheckTbl VALUES (10, 10)
GO
DELETE CheckTbl WHERE col1 = 10;

L'istruzione DELETE ha esito positivo, anche se il vincolo CHECK specifica che la tabella CheckTbl deve contenere almeno 1 riga.