Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cách tạo Ràng buộc KIỂM TRA trong SQL Server (Ví dụ T-SQL)

Trong SQL Server, bạn có thể tạo CHECK ràng buộc trong bảng để chỉ định các giá trị dữ liệu được chấp nhận trong một hoặc nhiều cột.

Nếu một bảng có CHECK ràng buộc về nó và bạn cố gắng cung cấp dữ liệu không tuân theo CHECK ràng buộc, hoạt động sẽ không thành công với một lỗi.

Điều này giúp duy trì tính toàn vẹn của dữ liệu, vì nó giúp ngăn dữ liệu không hợp lệ xâm nhập vào cơ sở dữ liệu.

Khi bạn tạo CHECK ràng buộc, bạn cung cấp một biểu thức logic trả về TRUE hoặc FALSE . Biểu thức logic này được sử dụng để kiểm tra dữ liệu.

CHECK các ràng buộc tương tự như các ràng buộc khóa ngoại vì chúng kiểm soát các giá trị được đặt trong một cột. Tuy nhiên, sự khác biệt là ở cách chúng xác định giá trị nào là hợp lệ:Ràng buộc khóa ngoại lấy danh sách các giá trị hợp lệ từ một bảng khác, trong khi CHECK các ràng buộc xác định các giá trị hợp lệ từ một biểu thức logic.

Các ràng buộc có thể được xác định ở cấp cột hoặc cấp bảng. Ràng buộc cấp cột chỉ áp dụng cho dữ liệu trong cột đó. Ràng buộc cấp bảng áp dụng cho toàn bộ hàng và kiểm tra dữ liệu từ nhiều cột.

Dưới đây là các ví dụ về cách tạo CHECK cấp cột và cấp bảng ràng buộc.

Ví dụ 1 - Tạo Ràng buộc KIỂM TRA Cấp Cột

Dưới đây là ví dụ về cách tạo CHECK cấp cột cơ bản tại thời điểm tạo bảng.

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

Trong trường hợp này, CHECK ràng buộc chỉ định rằng tất cả dữ liệu trong Price cột phải lớn hơn 0. Nói cách khác, giá không được bằng 0 và không được âm. Đây là ràng buộc cấp cột vì nó áp dụng cho dữ liệu trong một cột.

Bởi vì đây là một ràng buộc ở cấp độ cột, tôi có thể định nghĩa nó là một phần của cột (không có dấu phẩy). Vì vậy, tôi có thể đã làm điều này:

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

Dù bằng cách nào, hãy cố gắng chèn một giá trị không hợp lệ:

INSERT INTO ConstraintTest ( Price )
VALUES ( 0 );

Kết quả:

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

Ví dụ 2 - Thêm các cột khác và một ràng buộc kiểm tra ở cấp độ cột khác

Hãy thêm một số cột khác vào bảng của chúng tôi và sau đó thêm một cột khác CHECK ràng buộc.

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

Một trong các cột mới ghi lại số lượng thành viên trong nhóm. Trong trường hợp này, quy tắc kinh doanh là một nhóm phải có ít nhất 3 thành viên, nhưng không quá 15. Do đó, cơ sở dữ liệu sẽ ngăn chặn tình huống một nhóm có ít hơn 3 thành viên hoặc nhiều hơn 15.

Hãy thử chèn một giá trị không hợp lệ:

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

Kết quả:

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

Ví dụ 3 - Thêm Ràng buộc KIỂM TRA Cấp Bảng

Bây giờ, hãy thêm một ràng buộc cấp bảng. Thao tác này sẽ kiểm tra dữ liệu trong hai cột.

Nhân tiện, bạn không phải thêm một cột khác để thêm CHECK hạn chế. Bạn chỉ cần thêm ràng buộc vào chính nó.

Ví dụ:

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

Trong trường hợp này, tôi thêm một ràng buộc để đảm bảo rằng ngày kết thúc không bao giờ có thể sớm hơn ngày bắt đầu. Đây là kiểm tra dữ liệu trên hai cột và do đó là một ràng buộc cấp bảng.

Cố gắng chèn một giá trị không hợp lệ:

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

Kết quả:

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

Lưu ý rằng để kiểm tra ràng buộc này, tôi phải tăng số thành viên trong nhóm lên 3 để ngăn ràng buộc trước đó không được kích hoạt trước (CHECK các ràng buộc được xác thực theo thứ tự chúng được tạo).

Ví dụ 4 - Thay đổi Ràng buộc KIỂM TRA

Bạn thực sự không thể thay đổi một CHECK hạn chế. Nếu bạn cần thay đổi nó, bạn sẽ cần bỏ nó và tạo nó với định nghĩa mới.

Ví dụ:

ALTER TABLE ConstraintTest 
  DROP CONSTRAINT chkTeamSize;

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

Như đã đề cập, CHECK các ràng buộc được xác thực theo thứ tự chúng được tạo, vì vậy điều này có thể ảnh hưởng đến lỗi nào được phát hiện trước.

Do đó, trong trường hợp này, nếu tôi cố gắng chèn một giá trị không hợp lệ (và bao gồm cả những ngày không hợp lệ), thì những ngày không hợp lệ sẽ bị bắt trước:

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

Kết quả:

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

Vì vậy, để kiểm tra ràng buộc mới nhất của tôi, trước tiên tôi cần phải khắc phục vấn đề ngày tháng:

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

Kết quả:

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

Vì vậy, ràng buộc mới nhất của tôi đang hoạt động như mong đợi.

Ví dụ 5 - Ràng buộc KIỂM TRA và Cột IDENTITY

Vì vậy, bây giờ chúng tôi đã kiểm tra các ràng buộc, hãy tiếp tục và chèn dữ liệu hợp lệ:

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

Kết quả:

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

Cuối cùng, chúng tôi nhận được một chèn thành công.

Tuy nhiên, bạn sẽ nhận thấy rằng IDENTITY cột đã tăng lên 13.

Hãy nhớ rằng khi tôi tạo bảng lần đầu tiên, tôi đã xác định ConstraintTestId cột để sử dụng IDENTITY(1,1) , có nghĩa là nó phải bắt đầu từ 1 và tự động tăng lên 1 với mỗi lần chèn hàng.

Nhưng bây giờ cuối cùng tôi đã chèn hàng đầu tiên của mình, giá trị đã là 13. Đó là do IDENTITY cột được tăng lên ngay cả khi CHECK ràng buộc gây ra INSERT hoạt động không thành công.

Lưu ý rằng tôi đã thực hiện thêm một số lần chèn không thành công trong khi đưa ra các ví dụ cho bài viết này, vì vậy giá trị đã tăng lên một giá trị cao hơn những gì bạn sẽ nhận được nếu bạn chỉ cần làm theo từng bước với bài viết này.

Trong mọi trường hợp, hãy thực hiện một lần chèn không thành công cuối cùng, sau đó thực hiện một lần chèn thành công để xác nhận điều này.

Chèn không thành công:

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

Kết quả:

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

Chèn thành công:

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

SELECT * FROM ConstraintTest;

Kết quả:

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

Chúng ta có thể thấy rằng IDENTITY cột nhảy từ 13 đến 15, vì vậy nó rõ ràng tăng lên trong quá trình chèn không thành công.

Một số hạn chế của Ràng buộc CHECK

Dưới đây là một số hạn chế cần lưu ý khi làm việc với CHECK ràng buộc:

  • Điều kiện tìm kiếm phải đánh giá thành biểu thức Boolean và không thể tham chiếu đến bảng khác.
  • Biểu thức không được chứa các kiểu dữ liệu bí danh.
  • CHECK không thể xác định ràng buộc trên văn bản , ntext hoặc hình ảnh cột.

  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 Parallel Backup Restore -1

  2. Làm thế nào để chạy một thủ tục được lưu trữ trong máy chủ sql mỗi giờ?

  3. Làm cách nào để đặt chuỗi kết nối SQL Server?

  4. Chênh lệch thời gian SQL giữa hai ngày dẫn đến hh:mm:ss

  5. Mọi thứ bạn nên biết về SQL Server JOINS