13.1.20.6 CHECK Constraints
Prior to MySQL 8.0.16, CREATE TABLE
permits only the following limited version of table CHECK
constraint syntax, which is parsed and ignored:
CHECK (expr)
As of MySQL 8.0.16, CREATE TABLE
permits the core features of table and column CHECK
constraints, for all storage engines. CREATE TABLE
consente la seguenteCHECK
sintassi dei vincoli, sia per i vincoli di tabella che per i vincoli di colonna:
] CHECK (expr) ENFORCED]
L’opzionesymbol
specifica un nome per il vincolo. Se omesso, MySQL genera un nome dal nome della tabella, un letterale _chk_
e un numero ordinale (1, 2, 3,…). I nomi dei vincoli hanno una lunghezza massima di 64 caratteri. Sono case-sensitive, ma non sensibile all’accento.
expr
specifica la condizione di vincolo come espressione booleana che deve essere valutata aTRUE
oUNKNOWN
(per NULL
valori) per ogni riga della tabella. Se la condizione viene valutata FALSE
, non riesce e si verifica una violazione dei vincoli. L’effetto di una violazione dipende dall’istruzione in esecuzione, come descritto più avanti in questa sezione.
La clausola di applicazione opzionale indica se il vincolo viene applicato:
-
Se omesso o specificato come
ENFORCED
, il vincolo viene creato e applicato. -
Se specificato come
NOT ENFORCED
, il vincolo viene creato ma non applicato.
ACHECK
il vincolo è specificato come vincolo di tabella o di colonna:
-
Un vincolo di tabella non appare all’interno di una definizione di colonna e può fare riferimento a qualsiasi colonna o colonna di tabella. I riferimenti in avanti sono consentiti alle colonne che appaiono più avanti nella definizione della tabella.
-
Un vincolo di colonna appare all’interno di una definizione di colonna e può fare riferimento solo a quella colonna.
prendere in Considerazione questa tabella definizione:
CREATE TABLE t1( CHECK (c1 <> c2), c1 INT CHECK (c1 > 10), c2 INT CONSTRAINT c2_positive CHECK (c2 > 0), c3 INT CHECK (c3 < 100), CONSTRAINT c1_nonzero CHECK (c1 <> 0), CHECK (c1 > c3));
La definizione comprende i vincoli di tabella e di colonna vincoli, in nome e senza nome formati:
-
Il primo vincolo è un vincolo di tabella: Esso avviene al di fuori di qualsiasi definizione di colonna, quindi è possibile (e non) si riferiscono a più colonne di una tabella. Questo vincolo contiene riferimenti a colonne non ancora definite. Non viene specificato alcun nome di vincolo, quindi MySQL genera un nome.
-
I tre vincoli successivi sono vincoli di colonna: ognuno si verifica all’interno di una definizione di colonna e quindi può fare riferimento solo alla colonna definita. Uno dei vincoli è chiamato esplicitamente. MySQL genera un nome per ciascuno degli altri due.
-
Gli ultimi due vincoli sono vincoli di tabella. Uno di questi è chiamato esplicitamente. MySQL genera un nome per l’altro.
Come accennato, MySQL genera un nome per qualsiasi vincolo CHECK
specificato senza uno. Per visualizzare i nomi generati per la definizione della tabella precedente, utilizzareSHOW CREATE TABLE
:
mysql> SHOW CREATE TABLE t1\G*************************** 1. row *************************** Table: t1Create Table: CREATE TABLE `t1` ( `c1` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL, `c3` int(11) DEFAULT NULL, CONSTRAINT `c1_nonzero` CHECK ((`c1` <> 0)), CONSTRAINT `c2_positive` CHECK ((`c2` > 0)), CONSTRAINT `t1_chk_1` CHECK ((`c1` <> `c2`)), CONSTRAINT `t1_chk_2` CHECK ((`c1` > 10)), CONSTRAINT `t1_chk_3` CHECK ((`c3` < 100)), CONSTRAINT `t1_chk_4` CHECK ((`c1` > `c3`))) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
Lo standard SQL specifica che tutti i tipi di vincoli (chiave primaria, indice univoco, chiave esterna, controllo) appartengono allo stesso spazio dei nomi. In MySQL, ogni tipo di vincolo ha il proprio spazio dei nomi per schema (database). Di conseguenza,CHECK
i nomi dei vincoli devono essere univoci per schema; non ci sono due tabelle nello stesso schema in grado di condividere un CHECK
nome del vincolo. (Eccezione :una tabellaTEMPORARY
nasconde una tabella nonTEMPORARY
con lo stesso nome, quindi può avere anche gli stessi nomi dei vincoliCHECK
.)
L’inizio dei nomi dei vincoli generati con il nome della tabella aiuta a garantire l’unicità dello schema perché anche i nomi delle tabelle devono essere univoci all’interno dello schema.
CHECK
le espressioni di condizione devono rispettare le seguenti regole. Si verifica un errore se un’espressione contiene costrutti non consentiti.
-
Sono consentite colonne non generate e generate, ad eccezione delle colonne con l’attributo
AUTO_INCREMENT
e colonne in altre tabelle. -
Sono consentiti letterali, funzioni incorporate deterministiche e operatori. Una funzione è deterministica se, dati gli stessi dati nelle tabelle, più invocazioni producono lo stesso risultato, indipendentemente dall’utente connesso. Esempi di funzioni che non sono deterministiche e non riescono a questa definizione:
CONNECTION_ID()
CURRENT_USER()
NOW()
. -
Le funzioni memorizzate e le funzioni definite dall’utente non sono consentite.
-
I parametri di stored procedure e funzioni non sono consentiti.
-
Le variabili (variabili di sistema, variabili definite dall’utente e variabili locali del programma memorizzate) non sono consentite.
-
Le sottoquery non sono consentite.
Le azioni referenziali a chiave esterna (ON UPDATE
ON DELETE
) sono proibite sulle colonne utilizzate nei vincoli CHECK
. Likewise, CHECK
constraints are prohibited on columns used in foreign key referential actions.
CHECK
constraints are evaluated for INSERT
UPDATE
REPLACE
LOAD DATA
, and LOAD XML
statements and an error occurs if a constraint evaluates to FALSE
. Se si verifica un errore, la gestione delle modifiche già applicate differisce per i motori di archiviazione transazionale e non transazionale e dipende anche dal fatto che sia attiva la modalità SQL rigorosa, come descritto in modalità SQL rigorosa.
CHECK
vincoli vengono valutati per il INSERT IGNORE
UPDATE IGNORE
LOAD DATA ... IGNORE
e LOAD XML ... IGNORE
istruzioni e un messaggio di avviso se un vincolo restituisce FALSE
. L’inserimento o l’aggiornamento per qualsiasi riga incriminata viene saltato.
Se l’espressione di vincolo valuta un tipo di dati diverso dal tipo di colonna dichiarato, la coercizione implicita al tipo dichiarato avviene in base alle solite regole di conversione del tipo MySQL. Vedere Sezione 12.3, “Conversione del tipo nella valutazione delle espressioni”” Se la conversione del tipo non riesce o comporta una perdita di precisione, si verifica un errore.
Constraint expression evaluation utilizza la modalità SQL in vigore al momento della valutazione. Se qualsiasi componente dell’espressione dipende dalla modalità SQL, possono verificarsi risultati diversi per diversi usi della tabella a meno che la modalità SQL non sia la stessa durante tutti gli usi.