sql >> Database teknologi >  >> RDS >> Sqlserver

Sådan opretter du en CHECK-begrænsning i SQL Server (T-SQL-eksempler)

I SQL Server kan du oprette en CHECK begrænsning i en tabel for at angive de dataværdier, der er acceptable i en eller flere kolonner.

Hvis en tabel har en CHECK begrænsning på det, og du forsøger at levere data, der ikke er i overensstemmelse med CHECK begrænsning, vil operationen mislykkes med en fejl.

Dette hjælper med at bevare dataintegriteten, fordi det hjælper med at forhindre ugyldige data i at komme ind i databasen.

Når du opretter en CHECK begrænsning, giver du et logisk udtryk, der returnerer TRUE eller FALSE . Dette logiske udtryk er det, der bruges til at kontrollere dataene.

CHECK begrænsninger ligner fremmednøgle begrænsninger, fordi de styrer de værdier, der sættes i en kolonne. Forskellen ligger dog i, hvordan de bestemmer, hvilke værdier der er gyldige:Fremmednøglebegrænsninger henter listen over gyldige værdier fra en anden tabel, mens CHECK begrænsninger bestemmer de gyldige værdier fra et logisk udtryk.

Begrænsninger kan defineres på kolonneniveau eller tabelniveau. En begrænsning på kolonneniveau gælder kun for dataene i den kolonne. En begrænsning på tabelniveau gælder for hele rækken og kontrollerer data fra flere kolonner.

Nedenfor er eksempler på oprettelse af CHECK på både kolonneniveau og tabelniveau begrænsninger.

Eksempel 1 – Opret en kontrolbegrænsning på kolonneniveau

Her er et eksempel på oprettelse af en grundlæggende CHECK på kolonneniveau begrænsning på tidspunktet for oprettelse af en tabel.

CREATE TABLE ConstraintTest
(
  ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
  Price smallmoney NOT NULL,
  CONSTRAINT chkPrice CHECK (Price > 0)
);

I dette tilfælde er CHECK begrænsning angiver, at alle data i Price kolonne skal være større end 0. Med andre ord kan prisen ikke være nul, og den kan ikke være negativ. Dette er en begrænsning på kolonneniveau, fordi den gælder for data i én kolonne.

Fordi dette er en begrænsning på kolonneniveau, kunne jeg have defineret det som en del af kolonnen (uden komma). Så jeg kunne have gjort dette:

CREATE TABLE ConstraintTest
(
  ConstraintTestId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
  Price smallmoney NOT NULL CONSTRAINT chkPrice CHECK (Price > 0)
);

Uanset hvad, lad os prøve at indsætte en ugyldig værdi:

INSERT INTO ConstraintTest ( Price )
VALUES ( 0 );

Resultat:

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'.

Eksempel 2 – Tilføj flere kolonner og endnu en KONTROL-begrænsning på kolonneniveau

Lad os tilføje nogle flere kolonner til vores tabel og derefter tilføje endnu en CHECK på kolonneniveau begrænsning.

ALTER TABLE ConstraintTest
ADD 
  TeamSize tinyint NOT NULL,
  StartDate date NOT NULL,
  EndDate date NOT NULL,
  CONSTRAINT chkTeamSize CHECK (TeamSize >= 3 AND TeamSize <= 15)
  ;

En af de nye kolonner registrerer antallet af teammedlemmer. I dette tilfælde er forretningsreglen, at et team skal have mindst 3 medlemmer, men ikke mere end 15. Derfor bør databasen forhindre situationen, hvor et team har færre end 3 medlemmer eller mere end 15.

Lad os prøve at indsætte en ugyldig værdi:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 2, '2020-01-01', '1900-02-02' );

Resultat:

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'.

Eksempel 3 – Tilføj en KONTROL-begrænsning på tabelniveau

Lad os nu tilføje en begrænsning på tabelniveau. Dette vil kontrollere data i to kolonner.

I øvrigt behøver du ikke tilføje endnu en kolonne for at tilføje en CHECK begrænsning. Du kan blot tilføje begrænsningen af ​​sig selv.

Eksempel:

ALTER TABLE ConstraintTest
  ADD CONSTRAINT chkValidEndDate 
  CHECK (EndDate >= StartDate)
  ;

I dette tilfælde tilføjer jeg en begrænsning for at sikre, at slutdatoen aldrig kan være tidligere end startdatoen. Dette kontrollerer data på tværs af to kolonner og er derfor en begrænsning på tabelniveau.

Prøv at indsætte en ugyldig værdi:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 3, '2020-01-01', '1900-02-02' );

Resultat:

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".

Bemærk, at for at teste denne begrænsning, var jeg nødt til at øge teammedlemmerne til 3 for at forhindre den tidligere begrænsning i at blive udløst først (CHECK begrænsninger valideres i den rækkefølge, de oprettes).

Eksempel 4 – Ændre en CHECK-begrænsning

Du kan faktisk ikke ændre en CHECK begrænsning. Hvis du har brug for at ændre den, skal du droppe den og oprette den med den nye definition.

Eksempel:

ALTER TABLE ConstraintTest 
  DROP CONSTRAINT chkTeamSize;

ALTER TABLE ConstraintTest
  ADD CONSTRAINT chkTeamSize 
  CHECK (TeamSize >= 5 AND TeamSize <= 20)
  ;

Som nævnt CHECK begrænsninger valideres i den rækkefølge, de oprettes, så dette kan påvirke, hvilken fejl der fanges først.

Derfor i dette tilfælde, hvis jeg forsøger at indsætte en ugyldig værdi (og også inkludere ugyldige datoer), vil de ugyldige datoer blive fanget først:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 4, '2020-01-01', '1900-02-02' );

Resultat:

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".

Så for at tjekke min seneste begrænsning skal jeg først rette datoproblemet:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 4, '2020-01-01', '2020-02-02' );

Resultat:

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'.

Så min seneste begrænsning fungerer som forventet.

Eksempel 5 – KONTROLLER begrænsninger og IDENTITETSkolonner

Så nu hvor vi har testet begrænsningerne, lad os gå videre og indsætte gyldige data:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 1, 5, '2020-01-01', '2020-02-02' );

Resultat:

+--------------------+---------+------------+-------------+------------+
| ConstraintTestId   | Price   | TeamSize   | StartDate   | EndDate    |
|--------------------+---------+------------+-------------+------------|
| 13                 | 1.0000  | 5          | 2020-01-01  | 2020-02-02 |
+--------------------+---------+------------+-------------+------------+

Endelig får vi et vellykket indlæg.

Du vil dog bemærke, at IDENTITY kolonne er allerede steget til 13.

Husk, da jeg først oprettede tabellen, definerede jeg ConstraintTestId kolonne for at bruge IDENTITY(1,1) , hvilket betyder, at den skal starte ved 1 og automatisk stige med 1 for hver rækkeindsættelse.

Men nu hvor jeg endelig har indsat min første række, er værdien allerede 13. Det er fordi IDENTITY kolonnen øges, selv når en CHECK begrænsning forårsager INSERT operation mislykkes.

Bemærk, at jeg lavede et par ekstra mislykkede indsættelser, mens jeg kom med eksemplerne til denne artikel, så værdien er steget til en højere værdi end den, du får, hvis du blot følger med trin for trin med denne artikel.

Under alle omstændigheder, lad os lave en sidste mislykket indsættelse og derefter en vellykket for at bekræfte dette.

Indsættelse mislykkedes:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 2, 4, '2020-01-02', '2020-02-03' );

Resultat:

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'.

Vellykket indsættelse:

INSERT INTO ConstraintTest ( Price, TeamSize, StartDate, EndDate )
VALUES ( 2, 6, '2020-01-02', '2020-02-03' );

SELECT * FROM ConstraintTest;

Resultat:

+--------------------+---------+------------+-------------+------------+
| 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 |
+--------------------+---------+------------+-------------+------------+

Vi kan se, at IDENTITY kolonne hopper fra 13 til 15, så den steg tydeligvis under den mislykkede indsættelse.

Nogle begrænsninger af CHECK-begrænsninger

Her er et par begrænsninger, du skal være opmærksom på, når du arbejder med CHECK begrænsninger:

  • Søgebetingelsen skal evalueres til et boolesk udtryk og kan ikke henvise til en anden tabel.
  • Udtrykket kan ikke indeholde aliasdatatyper.
  • CHECK begrænsninger kan ikke defineres på tekst , ntekst eller billede kolonner.

  1. opdatering og komprimering af sqlite-database i Android

  2. Robolectric adgang til databasen giver en fejl

  3. Sådan bygger du ubegrænset menuniveau gennem PHP og mysql

  4. Flet en tabel og en ændringslog til en visning i PostgreSQL