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
tillater følgendeCHECK
begrensningssyntaks for både tabellbegrensninger og kolonnebegrensninger:
] CHECK (expr) ENFORCED]
den valgfrie symbol
angir et navn for begrensningen. Hvis utelatt, Genererer MySQL et navn fra tabellnavnet, en bokstavelig _chk_
og et ordenstall (1, 2, 3,…). Begrensningsnavn har en maksimal lengde på 64 tegn. De er saksfølsomme, men ikke aksentfølsomme.
expr
angir betingelsesbetingelsen som et boolsk uttrykk som må evalueres tilTRUE
ellerUNKNOWN
(forNULL
verdier) for hver rad i tabellen. Hvis betingelsen evalueres tilFALSE
, mislykkes den, og det oppstår et brudd på begrensningen. Effekten av et brudd avhenger av setningen som utføres, som beskrevet senere i denne delen.
den valgfrie håndhevelsesklausulen angir om begrensningen håndheves:
-
hvis utelatt eller angitt som
ENFORCED
, opprettes og håndheves begrensningen. -
hvis angitt som
NOT ENFORCED
, opprettes begrensningen, men håndheves ikke.
ACHECK
begrensning er angitt som enten en tabellbegrensning eller kolonnebegrensning:
-
en tabellbegrensning vises ikke i en kolonnedefinisjon og kan referere til en hvilken som helst tabellkolonne eller kolonner. Videresend referanser er tillatt for kolonner som vises senere i tabelldefinisjonen.
-
en kolonnebegrensning vises i en kolonnedefinisjon og kan bare referere til den kolonnen.
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));
definisjonen inkluderer tabellbegrensninger og kolonnebegrensninger, i navngitte og ikke navngitte formater:
-
den første begrensningen er en tabellbegrensning: den forekommer utenfor enhver kolonnedefinisjon, slik at den kan (og gjør) referere til flere tabellkolonner. Denne begrensningen inneholder videresendingsreferanser til kolonner som ikke er definert ennå. Ingen begrensningsnavn er angitt, Så MySQL genererer et navn.
-
de neste tre begrensningene er kolonnebegrensninger: Hver forekommer innenfor en kolonnedefinisjon, og kan dermed bare referere til kolonnen som defineres. En av begrensningene er navngitt eksplisitt. MySQL genererer et navn for hver av de to andre.
-
de to siste begrensningene er tabellbegrensninger. En av dem er navngitt eksplisitt. MySQL genererer et navn for den andre.
Som nevnt genererer MySQL et navn for noenCHECK
begrensning spesifisert uten en. Hvis DU vil se navnene som genereres for den foregående tabelldefinisjonen, bruker DU 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 angir at alle typer begrensninger (primærnøkkel, unik indeks, fremmednøkkel, sjekk) tilhører samme navneområde. I MySQL har hver begrensningstype sitt eget navneområde per skjema (database). Følgelig måCHECK
begrensningsnavn være unike per skjema; ingen to tabeller i samme skjema kan dele etCHECK
begrensningsnavn. (Unntak: en TEMPORARY
tabell skjuler en ikke – TEMPORARY
tabell med samme navn, slik at den kan ha sammeCHECK
begrensningsnavn også.)
Begynnelsen genererte betingelsesnavn med tabellnavnet bidrar til å sikre skjemaets unikhet fordi tabellnavn også må være unik i skjemaet.
CHECK
betingelsesuttrykk må overholde følgende regler. Det oppstår en feil hvis et uttrykk inneholder ugyldige konstruksjoner.
-
Ikke-Genererte og genererte kolonner er tillatt, unntatt kolonner med
AUTO_INCREMENT
attributtet og kolonner i andre tabeller. -
Bokstaver, deterministiske innebygde funksjoner og operatorer er tillatt. En funksjon er deterministisk hvis, gitt de samme dataene i tabeller, gir flere invokasjoner det samme resultatet, uavhengig av den tilkoblede brukeren. Eksempler på funksjoner som ikke er deterministiske og mislykkes i denne definisjonen:
CONNECTION_ID()
CURRENT_USER()
NOW()
. -
Lagrede funksjoner og brukerdefinerte funksjoner er ikke tillatt.
-
lagrede prosedyrer og funksjonsparametere er ikke tillatt.
-
Variabler (systemvariabler, brukerdefinerte variabler og lagrede program lokale variabler) er ikke tillatt.
-
Subqueries er ikke tillatt.
referansehandlinger For fremmednøkkel (ON UPDATE
ON DELETE
) er forbudt på kolonner som brukes i CHECK
begrensninger. 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
. Hvis det oppstår en feil, er håndtering av endringer som allerede er brukt, forskjellig for transaksjonelle og ikke-transaksjonelle lagringsmotorer, og avhenger også av om streng SQL-modus er i kraft, som beskrevet i Streng SQL-Modus.
CHECK
begrensninger evalueres forINSERT IGNORE
UPDATE IGNORE
LOAD DATA ... IGNORE
ogLOAD XML ... IGNORE
setninger og en advarsel oppstår hvis en begrensning evaluerer tilFALSE
. Sett inn eller oppdater for en hvilken som helst uakseptabel rad hoppes over.
hvis betingelsesuttrykket evalueres til en datatype som er forskjellig fra den deklarerte kolonnetypen, skjer implisitt tvang til den deklarerte typen i henhold til De vanlige MySQL-typekonverteringsreglene. Se Avsnitt 12.3, «Skriv Konvertering I Uttrykksevaluering». Hvis typekonvertering mislykkes eller resulterer i tap av presisjon, oppstår det en feil.
Evaluering Av Begrensningsuttrykk bruker SQL-modusen i kraft ved evalueringstidspunktet. Hvis en komponent i uttrykket avhenger AV SQL-modusen, kan det oppstå forskjellige resultater for ulike bruksområder av tabellen med mindre SQL-modusen er den samme under alle bruksområder.