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
erlaubt die folgende CHECK
Einschränkungssyntax für Tabellen- und Spaltenbeschränkungen:
] CHECK (expr) ENFORCED]
Das optionale symbol
gibt einen Namen für die Einschränkung an. Falls nicht angegeben, generiert MySQL einen Namen aus dem Tabellennamen, ein Literal _chk_
und eine Ordnungszahl (1, 2, 3, …). Einschränkungsnamen haben eine maximale Länge von 64 Zeichen. Sie sind case-sensitive, aber nicht accent-sensitive.
expr
gibt die Einschränkungsbedingung als booleschen Ausdruck an, der für jede Zeile der Tabelle TRUE
oder UNKNOWN
(für NULL
Werte) ausgewertet werden muss. Wenn die Bedingung FALSE
ergibt, schlägt sie fehl und es tritt eine Einschränkung auf. Die Auswirkung eines Verstoßes hängt von der ausgeführten Anweisung ab, wie weiter unten in diesem Abschnitt beschrieben.
Die optionale enforcement-Klausel gibt an, ob die Einschränkung erzwungen wird:
-
Wenn weggelassen oder als
ENFORCED
angegeben, wird die Einschränkung erstellt und erzwungen. -
Wenn als
NOT ENFORCED
angegeben, wird die Einschränkung erstellt, aber nicht erzwungen.
Eine CHECK
Einschränkung wird entweder als Tabelleneinschränkung oder Spaltenbeschränkung angegeben:
-
Eine Tabelleneinschränkung wird nicht in einer Spaltendefinition angezeigt und kann sich auf eine oder mehrere Tabellenspalten beziehen. Vorwärtsreferenzen sind auf Spalten zulässig, die später in der Tabellendefinition erscheinen.
-
Eine Spaltenbeschränkung wird innerhalb einer Spaltendefinition angezeigt und kann sich nur auf diese Spalte beziehen.
Betrachten Sie diese Tabellendefinition:
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));
Die Definition enthält Tabellenbeschränkungen und Spaltenbeschränkungen in benannten und unbenannten Formaten:
-
Die erste Einschränkung ist eine Tabellenbeschränkung: Sie tritt außerhalb jeder Spaltendefinition auf und kann (und wird) daher auf eine Tabelle verweisen zu mehreren Tabellenspalten. Diese Einschränkung enthält Vorwärtsverweise auf Spalten, die noch nicht definiert sind. Es wird kein Einschränkungsname angegeben, daher generiert MySQL einen Namen.
-
Die nächsten drei Einschränkungen sind Spaltenbeschränkungen: Jede tritt innerhalb einer Spaltendefinition auf und kann sich daher nur auf die zu definierende Spalte beziehen. Eine der Einschränkungen wird explizit benannt. MySQL generiert einen Namen für jede der beiden anderen.
-
Die letzten beiden Einschränkungen sind Tabellenbeschränkungen. Einer von ihnen wird explizit benannt. MySQL generiert einen Namen für den anderen.
Wie bereits erwähnt, generiert MySQL einen Namen für jede CHECK
Einschränkung, die ohne einen angegeben wurde. Um die für die vorhergehende Tabellendefinition generierten Namen anzuzeigen, verwenden Sie 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
Der SQL-Standard gibt an, dass alle Arten von Einschränkungen (Primärschlüssel, eindeutiger Index, Fremdschlüssel, Prüfung) zum selben Namespace gehören. In MySQL hat jeder Einschränkungstyp einen eigenen Namespace pro Schema (Datenbank). Folglich müssen CHECK
Einschränkungsnamen pro Schema eindeutig sein; keine zwei Tabellen im selben Schema können einen CHECK
Einschränkungsnamen gemeinsam nutzen. (Ausnahme: Eine TEMPORARY
-Tabelle verbirgt eine Nicht-TEMPORARY
-Tabelle mit demselben Namen, sodass sie auch dieselben CHECK
-Einschränkungsnamen haben kann.)
Wenn Sie generierte Einschränkungsnamen mit dem Tabellennamen beginnen, wird die Eindeutigkeit des Schemas sichergestellt, da Tabellennamen auch innerhalb des Schemas eindeutig sein müssen.
CHECK
Bedingungsausdrücke müssen die folgenden Regeln einhalten. Ein Fehler tritt auf, wenn ein Ausdruck unzulässige Konstrukte enthält.
-
Nicht generierte und generierte Spalten sind erlaubt, ausgenommen Spalten mit dem
AUTO_INCREMENT
Attribut und Spalten in anderen Tabellen. -
Literale, deterministische eingebaute Funktionen und Operatoren sind erlaubt. Eine Funktion ist deterministisch, wenn bei gleichen Daten in Tabellen mehrere Aufrufe unabhängig vom verbundenen Benutzer dasselbe Ergebnis liefern. Beispiele für Funktionen, die nicht deterministisch sind und diese Definition nicht erfüllen:
CONNECTION_ID()
CURRENT_USER()
NOW()
. -
Gespeicherte Funktionen und benutzerdefinierte Funktionen sind nicht zulässig.
-
Gespeicherte Prozeduren und Funktionsparameter sind nicht zulässig.
-
Variablen (Systemvariablen, benutzerdefinierte Variablen und lokale Programmvariablen) sind nicht zulässig.
-
Unterabfragen sind nicht zulässig.
Fremdschlüsselreferenzielle Aktionen (ON UPDATE
ON DELETE
) sind für Spalten verboten, die in CHECK
Einschränkungen verwendet werden. 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
. Wenn ein Fehler auftritt, unterscheidet sich die Behandlung bereits angewendeter Änderungen für transaktionale und nichttransaktionale Speichermodule und hängt auch davon ab, ob der strikte SQL-Modus aktiviert ist, wie unter Strikter SQL-Modus beschrieben.
CHECK
Einschränkungen werden für INSERT IGNORE
UPDATE IGNORE
LOAD DATA ... IGNORE
und LOAD XML ... IGNORE
ausgewertet und es wird eine Warnung ausgegeben, wenn ein constraint ergibt FALSE
. Das Einfügen oder Aktualisieren für eine fehlerhafte Zeile wird übersprungen.
Wenn der Einschränkungsausdruck einen Datentyp auswertet, der sich vom deklarierten Spaltentyp unterscheidet, erfolgt die implizite Erzwingung des deklarierten Typs gemäß den üblichen MySQL-Typkonvertierungsregeln. Siehe Abschnitt 12.3, „Typkonvertierung in der Ausdrucksauswertung“. Wenn die Typkonvertierung fehlschlägt oder zu einem Genauigkeitsverlust führt, tritt ein Fehler auf.
Die Auswertung von Einschränkungsausdrücken verwendet den zum Zeitpunkt der Auswertung gültigen SQL-Modus. Wenn eine Komponente des Ausdrucks vom SQL-Modus abhängt, können für verschiedene Verwendungen der Tabelle unterschiedliche Ergebnisse auftreten, es sei denn, der SQL-Modus ist bei allen Verwendungen gleich.