In SQL Server kunt u een CHECK
. aanmaken beperking in een tabel om de gegevenswaarden te specificeren die acceptabel zijn in een of meer kolommen.
Als een tafel een CHECK
. heeft beperking op, en u probeert gegevens te verstrekken die niet voldoen aan de CHECK
beperking, zal de bewerking mislukken met een fout.
Dit helpt de gegevensintegriteit te behouden, omdat het helpt voorkomen dat ongeldige gegevens de database binnenkomen.
Wanneer u een CHECK
. aanmaakt beperking, geeft u een logische expressie op die TRUE
. retourneert of FALSE
. Deze logische uitdrukking wordt gebruikt om de gegevens te controleren.
CHECK
beperkingen zijn vergelijkbaar met externe-sleutelbeperkingen omdat ze de waarden bepalen die in een kolom worden geplaatst. Het verschil zit hem echter in de manier waarop ze bepalen welke waarden geldig zijn:beperkingen voor externe sleutels halen de lijst met geldige waarden uit een andere tabel, terwijl CHECK
beperkingen bepalen de geldige waarden van een logische uitdrukking.
Beperkingen kunnen worden gedefinieerd op kolom- of tabelniveau. Een beperking op kolomniveau is alleen van toepassing op de gegevens in die kolom. Een beperking op tabelniveau is van toepassing op de hele rij en controleert gegevens uit meerdere kolommen.
Hieronder staan voorbeelden van het maken van zowel kolom- als tabelniveau CHECK
beperkingen.
Voorbeeld 1 – Maak een controlebeperking op kolomniveau
Hier is een voorbeeld van het maken van een CHECK
op kolomniveau beperking op het moment van het maken van een tabel.
CREATE TABLE ConstraintTest ( ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY, Price smallmoney NOT NULL, CONSTRAINT chkPrice CHECK (Price > 0) );
In dit geval is de CHECK
beperking specificeert dat alle gegevens in de Price
kolom moet groter zijn dan 0. Met andere woorden, de prijs kan niet nul zijn en mag niet negatief zijn. Dit is een beperking op kolomniveau omdat deze van toepassing is op gegevens in één kolom.
Omdat dit een beperking op kolomniveau is, had ik deze als onderdeel van de kolom kunnen definiëren (zonder de komma). Dus ik had dit kunnen doen:
CREATE TABLE ConstraintTest ( ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY, Price smallmoney NOT NULL CONSTRAINT chkPrice CHECK (Price > 0) );
Laten we hoe dan ook proberen een ongeldige waarde in te voegen:
INSERT INTO ConstraintTest ( Price ) VALUES ( 0 );
Resultaat:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkPrice". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'Price'.
Voorbeeld 2 – Voeg meer kolommen toe en nog een controlebeperking op kolomniveau
Laten we wat meer kolommen aan onze tabel toevoegen en dan nog een CHECK
op kolomniveau toevoegen beperking.
ALTER TABLE ConstraintTest ADD TeamSize tinyint NOT NULL, StartDate date NOT NULL, EndDate date NOT NULL, CONSTRAINT chkTeamSize CHECK (TeamSize >= 3 AND TeamSize <= 15) ;
Een van de nieuwe kolommen registreert het aantal teamleden. In dit geval is de bedrijfsregel dat een team minimaal 3 leden moet hebben, maar niet meer dan 15. Daarom moet de database voorkomen dat een team minder dan 3 of meer dan 15 leden heeft.
Laten we proberen een ongeldige waarde in te voeren:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 2, '2020-01-01', '1900-02-02' );
Resultaat:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Voorbeeld 3 – Een CONTROLE-beperking op tabelniveau toevoegen
Laten we nu een beperking op tabelniveau toevoegen. Hiermee worden gegevens in twee kolommen gecontroleerd.
Je hoeft trouwens niet nog een kolom toe te voegen om een CHECK
toe te voegen beperking. Je kunt de beperking gewoon zelf toevoegen.
Voorbeeld:
ALTER TABLE ConstraintTest ADD CONSTRAINT chkValidEndDate CHECK (EndDate >= StartDate) ;
In dit geval voeg ik een beperking toe om ervoor te zorgen dat de einddatum nooit eerder kan zijn dan de startdatum. Dit controleert gegevens over twee kolommen en is daarom een beperking op tabelniveau.
Probeer een ongeldige waarde in te voeren:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 3, '2020-01-01', '1900-02-02' );
Resultaat:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".
Merk op dat om deze beperking te testen, ik het aantal teamleden moest verhogen tot 3 om te voorkomen dat de vorige beperking eerst werd geactiveerd (CHECK
beperkingen worden gevalideerd in de volgorde waarin ze zijn gemaakt).
Voorbeeld 4 – Wijzig een CHECK-beperking
U kunt een CHECK
eigenlijk niet wijzigen beperking. Als je het moet wijzigen, moet je het laten vallen en het maken met de nieuwe definitie.
Voorbeeld:
ALTER TABLE ConstraintTest DROP CONSTRAINT chkTeamSize; ALTER TABLE ConstraintTest ADD CONSTRAINT chkTeamSize CHECK (TeamSize >= 5 AND TeamSize <= 20) ;
Zoals vermeld, CHECK
beperkingen worden gevalideerd in de volgorde waarin ze zijn gemaakt, dus dit kan van invloed zijn op welke fout het eerst wordt gedetecteerd.
Daarom, als ik in dit geval een ongeldige waarde probeer in te voegen (en ook ongeldige datums op te nemen), worden de ongeldige datums eerst opgemerkt:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 4, '2020-01-01', '1900-02-02' );
Resultaat:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkValidEndDate". The conflict occurred in database "Test", table "dbo.ConstraintTest".
Dus om mijn laatste beperking te controleren, moet ik eerst het datumprobleem oplossen:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 4, '2020-01-01', '2020-02-02' );
Resultaat:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Dus mijn laatste beperking werkt zoals verwacht.
Voorbeeld 5 – CONTROLEER beperkingen en IDENTITEIT-kolommen
Dus nu we de beperkingen hebben getest, laten we doorgaan en geldige gegevens invoegen:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 1, 5, '2020-01-01', '2020-02-02' );
Resultaat:
+--------------------+---------+------------+-------------+------------+ | ConstraintTestId | Price | TeamSize | StartDate | EndDate | |--------------------+---------+------------+-------------+------------| | 13 | 1.0000 | 5 | 2020-01-01 | 2020-02-02 | +--------------------+---------+------------+-------------+------------+
Eindelijk krijgen we een succesvolle invoeging.
U zult echter merken dat de IDENTITY
kolom is al verhoogd naar 13.
Weet je nog toen ik de tabel voor het eerst maakte, definieerde ik de ConstraintTestId
kolom om IDENTITY(1,1)
. te gebruiken , wat betekent dat het bij 1 moet beginnen en automatisch met 1 moet toenemen bij elke rij die wordt ingevoegd.
Maar nu ik eindelijk mijn eerste rij heb ingevoegd, is de waarde al 13. Dat komt omdat de IDENTITY
kolom wordt verhoogd, zelfs wanneer een CHECK
beperking veroorzaakt de INSERT
operatie mislukt.
Merk op dat ik een paar extra mislukte invoegingen heb gemaakt bij het bedenken van de voorbeelden voor dit artikel, dus de waarde is verhoogd naar een hogere waarde dan wat je krijgt als je dit artikel gewoon stap voor stap volgt.
Laten we in ieder geval een laatste mislukte insertie doen, en dan een succesvolle om dit te bevestigen.
Invoegen mislukt:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 2, 4, '2020-01-02', '2020-02-03' );
Resultaat:
Msg 547, Level 16, State 0, Line 1 The INSERT statement conflicted with the CHECK constraint "chkTeamSize". The conflict occurred in database "Test", table "dbo.ConstraintTest", column 'TeamSize'.
Succesvol invoegen:
INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate ) VALUES ( 2, 6, '2020-01-02', '2020-02-03' ); SELECT * FROM ConstraintTest;
Resultaat:
+--------------------+---------+------------+-------------+------------+ | ConstraintTestId | Price | TeamSize | StartDate | EndDate | |--------------------+---------+------------+-------------+------------| | 13 | 1.0000 | 5 | 2020-01-01 | 2020-02-02 | | 15 | 2.0000 | 6 | 2020-01-02 | 2020-02-03 | +--------------------+---------+------------+-------------+------------+
We kunnen zien dat de IDENTITY
kolom springt van 13 naar 15, dus het is duidelijk verhoogd tijdens de mislukte invoeging.
Enkele beperkingen van CHECK-beperkingen
Hier zijn een paar beperkingen waarmee u rekening moet houden bij het werken met CHECK
beperkingen:
- De zoekvoorwaarde moet een Booleaanse uitdrukking opleveren en mag niet verwijzen naar een andere tabel.
- De expressie mag geen alias-gegevenstypen bevatten.
CHECK
beperkingen kunnen niet worden gedefinieerd op tekst , ntekst , of afbeelding kolommen.