Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как да създадете ограничение CHECK в SQL Server (примери за T-SQL)

В SQL Server можете да създадете CHECK ограничение в таблица, за да посочите стойностите на данните, които са приемливи в една или повече колони.

Ако таблица има CHECK ограничение върху него и се опитвате да предоставите данни, които не отговарят на CHECK ограничение, операцията ще се провали с грешка.

Това помага да се поддържа целостта на данните, защото помага да се предотврати навлизането на невалидни данни в базата данни.

Когато създадете CHECK ограничение предоставяте логически израз, който връща TRUE или FALSE . Този логически израз се използва за проверка на данните.

CHECK ограниченията са подобни на ограниченията на външния ключ, защото контролират стойностите, които се поставят в колона. Разликата обаче е в това как определят кои стойности са валидни:ограниченията на външния ключ получават списъка с валидни стойности от друга таблица, докато CHECK ограниченията определят валидните стойности от логически израз.

Ограниченията могат да бъдат дефинирани на ниво колона или на ниво таблица. Ограничение на ниво колона се прилага само за данните в тази колона. Ограничение на ниво таблица се прилага за целия ред и проверява данни от множество колони.

По-долу са дадени примери за създаване както на ниво колона, така и на ниво таблица CHECK ограничения.

Пример 1 – Създайте ограничение CHECK на ниво колона

Ето пример за създаване на основен CHECK на ниво колона ограничение в момента на създаване на таблица.

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

В този случай CHECK ограничението указва, че всички данни в Price колоната трябва да е по-голяма от 0. С други думи, цената не може да бъде нула и не може да бъде отрицателна. Това е ограничение на ниво колона, защото се прилага за данни в една колона.

Тъй като това е ограничение на ниво колона, бих могъл да го дефинирам като част от колоната (без запетаята). Така че можех да направя това:

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

Така или иначе, нека се опитаме да вмъкнем невалидна стойност:

INSERT INTO ConstraintTest ( Price )
VALUES ( 0 );

Резултат:

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

Пример 2 – Добавете още колони и друго ограничение за ПРОВЕРКА на ниво колона

Нека добавим още няколко колони към нашата таблица и след това добавим още една колона CHECK ограничение.

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

Една от новите колони записва броя на членовете на екипа. В този случай бизнес правилото е, че екипът трябва да има най-малко 3 членове, но не повече от 15. Следователно базата данни трябва да предотвратява ситуацията, при която екипът има по-малко от 3 или повече от 15 членове.

Нека се опитаме да вмъкнем невалидна стойност:

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

Резултат:

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

Пример 3 – Добавете ограничение CHECK на ниво таблица

Сега нека добавим ограничение на ниво таблица. Това ще провери данните в две колони.

Между другото, не е нужно да добавяте друга колона, за да добавите CHECK ограничение. Можете просто да добавите ограничението от само себе си.

Пример:

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

В този случай добавям ограничение, за да гарантирам, че крайната дата никога не може да бъде по-рано от началната. Това е проверка на данни в две колони и следователно е ограничение на ниво таблица.

Опитайте да въведете невалидна стойност:

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

Резултат:

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

Имайте предвид, че за да тествам това ограничение, трябваше да увелича членовете на екипа до 3, за да предотвратя първото задействане на предишното ограничение (CHECK ограниченията се валидират в реда, в който са създадени).

Пример 4 – Промяна на ограничение CHECK

Всъщност не можете да промените CHECK ограничение. Ако трябва да го промените, ще трябва да го пуснете и да го създадете с новата дефиниция.

Пример:

ALTER TABLE ConstraintTest 
  DROP CONSTRAINT chkTeamSize;

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

Както бе споменато, CHECK Ограниченията се валидират в реда, в който са създадени, така че това може да повлияе коя грешка е уловена първа.

Следователно в този случай, ако се опитам да вмъкна невалидна стойност (и също така да включа невалидни дати), невалидните дати ще бъдат уловени първи:

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

Резултат:

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

Така че, за да проверя последното си ограничение, първо ще трябва да поправя проблема с датата:

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

Резултат:

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

Така че последното ми ограничение работи според очакванията.

Пример 5 – ПРОВЕРКА на ограничения и колони ИДЕНТИЧНОСТ

Така че сега, след като тествахме ограниченията, нека да продължим и да вмъкнем валидни данни:

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

Резултат:

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

Накрая получаваме успешно вмъкване.

Въпреки това ще забележите, че IDENTITY колоната вече се е увеличила до 13.

Не забравяйте, че когато за първи път създадох таблицата, дефинирах ConstraintTestId колона, за да използвате IDENTITY(1,1) , което означава, че трябва да започне от 1 и автоматично да се увеличава с 1 с всяко вмъкване на ред.

Но сега, когато най-накрая вмъкнах първия си ред, стойността вече е 13. Това е защото IDENTITY колоната се увеличава дори когато CHECK ограничението причинява INSERT операция е неуспешна.

Имайте предвид, че направих няколко допълнителни неуспешни вмъквания, докато измислих примерите за тази статия, така че стойността се увеличи до по-висока стойност от тази, която ще получите, ако просто следвате стъпка по стъпка с тази статия.

Във всеки случай, нека направим едно последно неуспешно вмъкване и след това успешно, за да потвърдим това.

Неуспешно вмъкване:

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

Резултат:

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

Успешно вмъкване:

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

SELECT * FROM ConstraintTest;

Резултат:

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

Можем да видим, че IDENTITY колоната скача от 13 на 15, така че очевидно се е увеличила по време на неуспешното вмъкване.

Някои ограничения на ограниченията на CHECK

Ето няколко ограничения, които трябва да имате предвид, когато работите с CHECK ограничения:

  • Условието за търсене трябва да се оценява като булев израз и не може да препраща към друга таблица.
  • Изразът не може да съдържа типове данни за псевдоним.
  • CHECK ограниченията не могат да бъдат дефинирани за текст , ntext , или изображение колони.

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Връщане на стойност от команда на SQL Server Insert с помощта на c#

  2. съхранени процедури с sqlAlchemy

  3. Архивиране на SQL Server 2017 -3

  4. Функция IndexOf в T-SQL

  5. Как мога да видя всички разрешени специални знаци в полето varchar или char в SQL Server?