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
staat de volgende CHECK
constraint syntaxis toe, voor zowel tabelbeperkingen als kolombeperkingen:
] CHECK (expr) ENFORCED]
De optionele symbol
specificeert een naam voor de constraint. Indien weggelaten, genereert MySQL een naam uit de tabelnaam, een letterlijke _chk_
, en een ordinaal getal (1, 2, 3, …). Beperkte namen hebben een maximale lengte van 64 tekens. Ze zijn hoofdlettergevoelig, maar niet accentgevoelig.
expr
specificeert de constraintvoorwaarde als een Booleaanse uitdrukking die moet evalueren naar TRUE
of UNKNOWN
(voor NULL
waarden) voor elke rij van de tabel. Als de voorwaarde evalueert naar FALSE
, mislukt het en treedt een beperking overtreding op. Het effect van een overtreding hangt af van de uitvoering van de verklaring, zoals verderop in deze sectie wordt beschreven.
De facultatieve afdwingingclausule geeft aan of de beperking wordt afgedwongen:
-
indien weggelaten of gespecificeerd als
ENFORCED
, wordt de beperking gemaakt en afgedwongen. -
indien gespecificeerd als
NOT ENFORCED
, wordt de beperking aangemaakt maar niet afgedwongen.
a CHECK
beperking is gespecificeerd als een tabelbeperking of kolombeperking:
-
een tabelbeperking komt niet voor binnen een kolomdefinitie en kan verwijzen naar elke kolom of kolom. Voorwaartse verwijzingen zijn toegestaan naar kolommen die later in de definitie van de tabel voorkomen.
-
een kolombeperking verschijnt binnen een kolomdefinitie en kan alleen naar die kolom verwijzen.
beschouw deze tabeldefinitie als volgt:
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));
de definitie omvat tabelbeperkingen en kolombeperkingen, in benoemde en naamloze formaten:
-
de eerste beperking is een tabelbeperking: deze komt voor buiten elke kolomdefinitie, dus het kan (en doet) verwijzen naar naar meerdere tabelkolommen. Deze beperking bevat voorwaartse verwijzingen naar nog niet gedefinieerde kolommen. Er is geen beperkte naam opgegeven, dus MySQL genereert een naam.
-
de volgende drie beperkingen zijn kolombeperkingen: elk komt voor binnen een kolomdefinitie en kan dus alleen verwijzen naar de kolom die wordt gedefinieerd. Een van de beperkingen wordt expliciet genoemd. MySQL genereert een naam voor elk van de andere twee.
-
de laatste twee beperkingen zijn tabelbeperkingen. Een van hen wordt expliciet genoemd. MySQL genereert een naam voor de andere.
zoals gezegd genereert MySQL een naam voor elkeCHECK
beperking gespecificeerd zonder één. Gebruik SHOW 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
De SQL-standaard geeft aan dat alle typen beperkingen (primaire sleutel, unieke index, vreemde sleutel, controle) tot dezelfde naamruimte behoren. In MySQL heeft elk constrainttype zijn eigen naamruimte per schema (database). Bijgevolg moetenCHECK
constraintnamen uniek zijn per schema; geen twee tabellen in hetzelfde schema kunnen een CHECK
constraint naam delen. (Uitzondering: eenTEMPORARY
tabel verbergt een niet-TEMPORARY
tabel met dezelfde naam, dus het kan dezelfde CHECK
constraintnamen hebben.)
beginnende gegenereerde constraintnamen met de tabelnaam helpen om de uniciteit van het schema te garanderen, omdat tabelnamen ook uniek moeten zijn binnen het schema.
CHECK
voorwaarde expressies moeten voldoen aan de volgende regels. Er treedt een fout op als een expressie niet-toegestane constructies bevat.
-
niet-gegenereerde en gegenereerde kolommen zijn toegestaan, behalve kolommen met het
AUTO_INCREMENT
attribuut en kolommen in andere tabellen. -
Literalen, deterministische ingebouwde functies en operators zijn toegestaan. Een functie is deterministisch als, gegeven dezelfde gegevens in tabellen, meerdere aanroepingen hetzelfde resultaat opleveren, onafhankelijk van de verbonden gebruiker. Voorbeelden van functies die niet-deterministisch zijn en niet aan deze definitie voldoen:
CONNECTION_ID()
CURRENT_USER()
NOW()
. -
opgeslagen functies en door de gebruiker gedefinieerde functies zijn niet toegestaan.
-
opgeslagen procedure – en functieparameters zijn niet toegestaan.
-
variabelen (systeemvariabelen, door de gebruiker gedefinieerde variabelen en opgeslagen lokale programmavariabelen) zijn niet toegestaan.
-
Subqueries zijn niet toegestaan.
buitenlandse sleutelreferentiële acties (ON UPDATE
ON DELETE
) zijn verboden op kolommen die worden gebruikt in CHECK
beperkingen. 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
. Als er een fout optreedt, verschilt de afhandeling van reeds toegepaste wijzigingen voor transactionele en niet-transactionele opslagmotoren, en hangt ook af van de vraag of de strikte SQL-modus van kracht is, zoals beschreven in de strikte SQL-modus.
CHECK
beperkingen worden geëvalueerd voor INSERT IGNORE
UPDATE IGNORE
LOAD DATA ... IGNORE
, en LOAD XML ... IGNORE
constraint evalueert naar FALSE
. Het invoegen of bijwerken voor een gewraakte rij wordt overgeslagen.
als de constraint expressie evalueert naar een gegevenstype dat verschilt van het gedeclareerde kolomtype, vindt impliciete dwang voor het gedeclareerde type plaats volgens de gebruikelijke MySQL type-conversie regels. Zie paragraaf 12.3, “typeconversie in Expressieevaluatie”. Als type conversie mislukt of resulteert in een verlies van precisie, een fout optreedt.
Constraint expression evaluation gebruikt de SQL-modus die van kracht is op het moment van evaluatie. Als een onderdeel van de expressie afhankelijk is van de SQL-modus, kunnen verschillende resultaten optreden voor verschillende toepassingen van de tabel, tenzij de SQL-modus hetzelfde is voor alle toepassingen.