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
a következő CHECK
kényszer szintaxisát engedélyezi mind a táblázat, mind az oszlop kényszereihez:
] CHECK (expr) ENFORCED]
Az opcionális symbol
megadja a kényszer nevét. Ha elhagyjuk, a MySQL létrehoz egy nevet a tábla nevéből, egy literális _chk_
, valamint egy sorszámot (1, 2, 3, …). A kényszernevek maximális hossza 64 karakter. Nagybetűérzékeny, de nem akcentusérzékeny.
expr
a kényszer feltételét logikai kifejezésként adja meg, amelyet a táblázat minden sorához TRUE
vagy UNKNOWN
NULL
értékek esetén) kell értékelni. Ha a feltétel értéke FALSE
, akkor sikertelen, és kényszer-megsértés történik. A jogsértés hatása a végrehajtandó utasítástól függ, amint azt később ebben a szakaszban ismertetjük.
Az opcionális végrehajtási záradék jelzi, hogy a kényszer végrehajtásra került-e:
-
ha elhagyjuk, vagy
ENFORCED
a kényszer létrejön és érvényre jut. -
ha
NOT ENFORCED
van megadva, a kényszer létrejön, de nem érvényesül.
a CHECK
a kényszer táblázatkényszer vagy oszlopkényszer formájában van megadva:
-
a táblázatkényszer nem jelenik meg az oszlopdefiníción belül, és hivatkozhat bármely táblázatoszlopra vagy oszlopra. A táblázat definíciójában később megjelenő oszlopokra továbbítási hivatkozások megengedettek.
-
az oszlopdefiníción belül megjelenik egy oszlopkorlátozás, amely csak erre az oszlopra hivatkozhat.
fontolja meg ezt a táblázat definíciót:
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));
a definíció táblázatkorlátokat és oszlopkorlátokat tartalmaz, megnevezett és meg nem nevezett formátumokban:
-
Az első kényszer egy táblázatkorlátozás: bármely oszlopdefiníción kívül történik, ezért a definíció nem tartalmazza a lehet (és nem) több táblaoszlopra hivatkozni. Ez a korlátozás a még nem definiált oszlopokra mutató hivatkozásokat tartalmaz. Nincs korlátozás neve megadva, így a MySQL létrehoz egy nevet.
-
a következő három korlátozás oszlopkorlátozás: mindegyik egy oszlopdefiníción belül történik, így csak a definiált oszlopra vonatkozhat. Az egyik korlátozást kifejezetten megnevezik. A MySQL nevet generál a másik kettő számára.
-
az utolsó két korlátozás táblázatkorlátozás. Az egyiket kifejezetten nevezik. A MySQL létrehoz egy nevet a másiknak.
mint említettük, a MySQL nevet generál minden CHECK
korlátozás nélkül megadott. Az előző tábladefinícióhoz létrehozott nevek megtekintéséhez használja a 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
az SQL szabvány meghatározza, hogy minden típusú korlátozás (elsődleges kulcs, egyedi index, idegen kulcs, ellenőrzés) ugyanahhoz a névtérhez tartozik. A MySQL-ben minden kényszertípusnak saját névtere van sémánként (adatbázis). Következésképpen CHECK
a kényszerneveknek sémánként egyedinek kell lenniük; ugyanazon séma két táblája nem oszthatja meg a CHECK
kényszer nevét. (Kivétel: aTEMPORARY
tábla elrejti a nem-TEMPORARY
tábla az azonos nevű, így lehet ugyanaz aCHECK
kényszer nevek is.)
a létrehozott kényszernevek kezdete a tábla nevével segít biztosítani a séma egyediségét, mivel a táblaneveknek is egyedinek kell lenniük a sémán belül.
CHECK
a feltétel kifejezéseknek be kell tartaniuk a következő szabályokat. Hiba lép fel, ha egy kifejezés nem engedélyezett konstrukciókat tartalmaz.
-
nem generált és generált oszlopok megengedettek, kivéve a
AUTO_INCREMENT
attribútummal rendelkező oszlopokat és más táblázatok oszlopait. -
literálok, determinisztikus beépített függvények és operátorok megengedettek. Egy függvény akkor determinisztikus, ha a táblázatokban szereplő adatok alapján több meghívás ugyanazt az eredményt eredményezi, függetlenül a csatlakoztatott felhasználótól. Példák nem determinisztikus függvényekre, amelyek nem felelnek meg ennek a meghatározásnak:
CONNECTION_ID()
CURRENT_USER()
NOW()
. -
tárolt és felhasználó által definiált funkciók nem engedélyezettek.
-
tárolt eljárás és funkció paraméterek nem engedélyezettek.
-
változók (rendszerváltozók, felhasználó által definiált változók és tárolt program lokális változók) nem engedélyezettek.
-
Alkérdezések nem engedélyezettek.
idegen kulcs hivatkozási műveletek (ON UPDATE
ON DELETE
) tilosak a CHECK
megszorításokban használt oszlopokon. 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
. Hiba esetén a már alkalmazott módosítások kezelése eltér a tranzakciós és a nem tranzakciós tárolómotoroknál, és attól is függ, hogy a szigorú SQL mód van-e érvényben, amint azt a szigorú SQL módban leírtuk.
CHECK
a megszorítások kiértékelése INSERT IGNORE
UPDATE IGNORE
LOAD DATA ... IGNORE
és LOAD XML ... IGNORE
utasítások és figyelmeztetés akkor fordul elő, ha a kényszer értéke FALSE
. Bármely jogsértő sor beszúrása vagy frissítése kihagyásra kerül.
Ha a kényszer kifejezés olyan adattípusra értékel, amely eltér a deklarált oszloptípustól, akkor a deklarált típusra való implicit kényszerítés a szokásos MySQL típuskonverziós szabályok szerint történik. Lásd a 12.3. szakaszt, “típuskonverzió a kifejezés kiértékelésében”. Ha a típuskonverzió sikertelen vagy a pontosság elvesztését eredményezi, hiba lép fel.
a kényszer kifejezés kiértékelése Az értékelés időpontjában érvényes SQL módot használja. Ha a kifejezés bármely összetevője az SQL módtól függ, különböző eredmények fordulhatnak elő a táblázat különböző felhasználásainál, kivéve, ha az SQL mód minden használat során azonos.