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
tillåter följandeCHECK
begränsningssyntax, för både tabellbegränsningar och kolumnbegränsningar:
] CHECK (expr) ENFORCED]
det valfria symbol
anger ett namn för begränsningen. Om det utelämnas genererar MySQL ett namn från tabellnamnet, ett bokstavligt _chk_
och ett ordinärt tal (1, 2, 3,…). Begränsningsnamn har en maximal längd på 64 tecken. De är skiftlägeskänsliga, men inte accentkänsliga.
expr
anger begränsningsvillkoret som ett booleskt uttryck som måste utvärderas tillTRUE
ellerUNKNOWN
(förNULL
värden) för varje rad i tabellen. Om villkoret utvärderas till FALSE
, misslyckas det och en begränsningsöverträdelse inträffar. Effekten av en överträdelse beror på uttalandet som utförs, som beskrivs senare i detta avsnitt.
den valfria verkställighetsklausulen anger om begränsningen verkställs:
-
om den utelämnas eller anges som
ENFORCED
skapas och verkställs begränsningen. -
om det anges som
NOT ENFORCED
skapas begränsningen men tillämpas inte.
A CHECK
begränsning anges som antingen en tabellbegränsning eller kolumnbegränsning:
-
en tabellbegränsning visas inte inom en kolumndefinition och kan hänvisa till valfri tabellkolumn eller kolumner. Framåtreferenser är tillåtna för kolumner som visas senare i tabelldefinitionen.
-
en kolumnbegränsning visas inom en kolumndefinition och kan endast hänvisa till den kolumnen.
Tänk på denna tabelldefinition:
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));
definitionen innehåller tabellbegränsningar och kolumnbegränsningar, i namngivna och namnlösa format:
-
den första begränsningen är en tabellbegränsning: den förekommer utanför någon kolumndefinition, så det är inte nödvändigt att använda kan (och gör) hänvisa till flera tabellkolumner. Denna begränsning innehåller vidarebefordringsreferenser till kolumner som ännu inte har definierats. Inget begränsningsnamn anges, så MySQL genererar ett namn.
-
de följande tre begränsningarna är kolumnbegränsningar: var och en förekommer inom en kolumndefinition och kan således endast hänvisa till den kolumn som definieras. En av begränsningarna heter uttryckligen. MySQL genererar ett namn för var och en av de andra två.
-
de två sista begränsningarna är tabellbegränsningar. En av dem heter uttryckligen. MySQL genererar ett namn för den andra.
Som nämnts genererar MySQL ett namn för alla CHECK
begränsningar som anges utan en. För att se Namnen som genererats för föregående tabelldefinition, använd 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
SQL-standarden anger att alla typer av begränsningar (primärnyckel, unikt index, utländsk nyckel, check) tillhör samma namnområde. I MySQL har varje begränsningstyp sitt eget namnområde per schema (databas). Följaktligen måste CHECK
begränsningsnamn vara unika per schema; inga två tabeller i samma schema kan dela ettCHECK
begränsningsnamn. (Undantag: en TEMPORARY
tabell döljer en icke – TEMPORARY
tabell med samma namn, så det kan ha samma CHECK
begränsningsnamn också.)
början av genererade begränsningsnamn med tabellnamnet hjälper till att säkerställa schemans unikhet eftersom tabellnamn också måste vara unika i schemat.
CHECK
villkorsuttryck måste följa följande regler. Ett fel uppstår om ett uttryck innehåller otillåtna konstruktioner.
-
icke-genererade och genererade kolumner är tillåtna, utom kolumner med attributet
AUTO_INCREMENT
och kolumner i andra tabeller. -
bokstav, deterministiska inbyggda funktioner och operatorer är tillåtna. En funktion är deterministisk om, givet samma data i tabeller, flera anrop ger samma resultat, oberoende av den anslutna användaren. Exempel på funktioner som inte är deterministiska och misslyckas med denna definition:
CONNECTION_ID()
CURRENT_USER()
NOW()
. -
lagrade funktioner och användardefinierade funktioner är inte tillåtna.
-
lagrad procedur och funktionsparametrar är inte tillåtna.
-
variabler (Systemvariabler, användardefinierade variabler och lagrade programlokala variabler) är inte tillåtna.
-
underfrågor är inte tillåtna.
Referensåtgärder med utländsk nyckel (ON UPDATE
ON DELETE
) är förbjudna på kolumner som används i CHECK
begränsningar. 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
. Om ett fel inträffar skiljer sig hanteringen av ändringar som redan tillämpats för transaktions-och icke-transaktionslagringsmotorer och beror också på om strikt SQL-läge är i kraft, som beskrivs i strikt SQL-läge.
CHECK
begränsningar utvärderas förINSERT IGNORE
UPDATE IGNORE
LOAD DATA ... IGNORE
ochLOAD XML ... IGNORE
uttalanden och en varning uppstår om en begränsning utvärderas tillFALSE
. Infoga eller uppdatera för någon felande rad hoppas över.
om begränsningsuttrycket utvärderas till en datatyp som skiljer sig från den deklarerade kolumntypen, sker implicit tvång till den deklarerade typen enligt de vanliga MySQL-typkonverteringsreglerna. Se avsnitt 12.3, ”Typkonvertering i Uttrycksutvärdering”. Om typkonvertering misslyckas eller resulterar i förlust av precision uppstår ett fel.
utvärdering av Begränsningsuttryck använder SQL-läget i kraft vid utvärderingstidpunkten. Om någon komponent i uttrycket beror på SQL-läget kan olika resultat uppstå för olika användningar av tabellen om inte SQL-läget är detsamma under alla användningar.