Trong bài viết này, chúng tôi sẽ nói về các ràng buộc KIỂM TRA. Chúng ta sẽ xem cách thêm ràng buộc KIỂM TRA vào các cột của bảng SQL Server và thảo luận về những cạm bẫy bạn có thể gặp phải khi sử dụng loại ràng buộc SQL Server này.
KIỂM TRA các vấn đề cơ bản về ràng buộc
Ràng buộc CHECK chỉ đơn giản là các câu lệnh điều kiện (các vị từ trả về TRUE hoặc FALSE) tham chiếu đến các cột của bảng để duy trì tính toàn vẹn của dữ liệu. Khi người ta chèn dữ liệu vào một cột hoặc một số cột trong một hàng, ràng buộc CHECK sẽ có hiệu lực. Họ đánh giá dữ liệu sẽ được chèn vào. Trong trường hợp dữ liệu không đáp ứng điều kiện được chỉ định trong ràng buộc CHECK, việc chèn không thành công.
Hãy xem xét ví dụ sau:
Cần đặt giới hạn cho cột Lương để cột này chỉ lưu trữ các giá trị dương không vượt quá 150.000 đô la. Câu lệnh điều kiện sẽ có dạng như sau:( Lương > =0 và Lương <=150000). Trong khi cố gắng chèn các giá trị âm, vị từ sẽ dẫn đến FALSE và việc chèn sẽ không thành công.
Có thể thêm ràng buộc KIỂM TRA vào một hoặc nhiều cột. Thêm ràng buộc KIỂM TRA nhiều cột có thể được triển khai ở cấp bảng.
Làm việc với các ràng buộc KIỂM TRA
Cách tạo Ràng buộc KIỂM TRA trong SSMS
-
Trong Trình khám phá đối tượng , điều hướng đến một bảng bắt buộc.
-
Nhấp chuột phải vào Ràng buộc thư mục rồi đến c liếm Ràng buộc mới…
-
Trong ngăn bên phải của Kiểm tra Ràng buộc hộp thoại, nhấp vào Biểu thức và sau đó nhấp vào nút dấu chấm lửng.
-
Nhập biểu thức ràng buộc KIỂM TRA vào trường văn bản của Biểu thức ràng buộc Kiểm tra hộp thoại. Ví dụ:để chỉ cho phép mã zip bảy chữ số trong cột Zip, biểu thức có thể trông như sau:
Trong Trình thiết kế bảng , bạn có thể thiết lập các quy tắc để thực thi ràng buộc.
Ràng buộc KIỂM TRA trên TẠO BẢNG
Hãy xem xét ví dụ sau:
Bắt buộc phải tạo một bảng lưu trữ dữ liệu về khách hàng của ngân hàng và điền vào bảng này với dữ liệu thử nghiệm. Bảng sẽ bao gồm các cột sau:Id Khách hàng, Tên, Họ, Trạng thái, Điện thoại, Thành phố, Tiểu bang và Mã zip.
Trong khi phát triển bảng, chúng ta phải xem xét các yếu tố sau:
-
Định dạng ZIP cơ bản bao gồm năm chữ số.
-
Số điện thoại tiêu chuẩn của Mỹ có mười chữ số, chẳng hạn như (555) 555-1234
-
Chữ viết tắt gồm hai chữ cái được sử dụng để đại diện cho các bộ phận chính trị của Hoa Kỳ cho địa chỉ bưu điện, xử lý dữ liệu, chữ viết tắt chung và các mục đích khác.
Nhiệm vụ là cung cấp tính nhất quán dữ liệu cho bảng. Bắt buộc phải cấm chèn các số điện thoại 12 chữ số và khóa 6 chữ số, v.v. Để làm điều này, SQL Server cho phép chúng tôi thêm một hoặc nhiều ràng buộc KIỂM TRA cho mỗi cột trong bảng.
Trong phần trước, chúng ta đã xem xét một cách tạo ràng buộc KIỂM TRA trong SSMS. Bây giờ, chúng ta sẽ thảo luận về cách tạo ràng buộc với sự trợ giúp của T-SQL.
Tập lệnh sau cho biết cách tạo ràng buộc KIỂM TRA trên cột Zip:
CREATE TABLE Customers ( Customer_Id tinyint NOT NULL, [First Name] varchar(50), [Last Name] varchar(50), Status varchar(50), Phone tinyint, Address varchar(50), State varchar(50), Zip tinyint, Email varchar(50), [Credit Limit] INT NULL, CONSTRAINT CK_Zip CHECK (Zip LIKE REPLICATE ('[0-9]', 5)) --Check Constraint Condition )
Bây giờ, hãy xem những gì chúng ta nhận được khi cố gắng chèn giá trị 6 chữ số vào cột Zip:
INSERT INTO dbo.Customers (Customer_Id, [First Name], [Last Name], Status, Phone, Address, State, Zip, Email) SELECT 1, 'James', 'Madison', 'Mr', 555-555-1234, 'Madison street, 12', 'LA', 123456, NULL GO
Chèn không thành công và SQL Server hiển thị ngăn chặn sau:
Cho đến nay, rất tốt.
Biểu thức CASE trong ràng buộc KIỂM TRA
Giả sử rằng ngân hàng có một quy tắc kinh doanh để đặt hạn mức tín dụng cho cư dân của tiểu bang Louisiana là dưới 150.000 đô la. Chúng tôi sẽ thực hiện yêu cầu này bằng cách thêm ràng buộc KIỂM TRA vào cột Hạn mức tín dụng:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Credit_Limit CHECK (State='LA' AND [Credit Limit] <= 150000) GO INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (1, 'James Black', 'Mr', 5558787, 'LA', 46853, '[email protected]', 120000); GO INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (2, 'Mark Spencer', 'Mr', 3332244, 'NY', 23487, '[email protected]', 200000); GO
Khi chúng tôi thực hiện câu lệnh trên, chúng tôi gặp lỗi sau:
Câu lệnh INSERT xung đột với ràng buộc CHECK. Điều gì đã xảy ra?
Chúng ta hãy xem xét kỹ hơn truy vấn. Lưu ý rằng ràng buộc CHECK chỉ cho phép các giá trị ‘LA’ cho cột Trạng thái. Đồng thời, các giá trị trong cột Tín dụng không được vượt quá 150000.
Tương tự, ràng buộc CHECK sẽ không cho phép viết các mã trạng thái khác trong cột.
Do đó, chúng ta cần sửa đổi điều kiện. Theo logic kinh doanh, ngân hàng cung cấp $ 150000 trong hạn mức tín dụng cho cư dân Louisiana. Đồng thời, giá trị này có thể thay đổi đối với các cư dân khác.
Để triển khai trường hợp này, chúng tôi sẽ sử dụng mệnh đề CASE bên trong ràng buộc CHECK:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Credit_Limit CHECK (CASE WHEN State='LA' AND [Credit Limit] <= 150000 THEN 1 ELSE 0 END = 1) GO
Biểu thức này hoàn toàn đáp ứng logic nghiệp vụ.
Giá trị NULL trong ràng buộc KIỂM TRA
Ngân hàng chia khách hàng của mình thành các phân khúc. Cột Trạng thái chứa dữ liệu xác định xem khách hàng là VIP hay thường xuyên. Số tiền tối đa của hạn mức tín dụng cho khách hàng thông thường là $ 200.000. Các VIP có thể kiếm được 500.000 đô la.
Ràng buộc KIỂM TRA có thể trông như sau:
ALTER TABLE dbo.Customers ADD CONSTRAINT CK_Status_Credit_Limit CHECK (Status = 'VIP' OR Status = 'Regular') GO
Lưu ý rằng ràng buộc CHECK cho phép chèn NULL vào cột Trạng thái (miễn là không có ràng buộc NOT NULL nào được xác định rõ ràng). Ràng buộc CHECK đánh giá các giá trị và trả về TRUE hoặc FALSE. Nó đánh giá NULL là UNKNOWN. Do đó, NULLs sẽ không gây ra lỗi. Điều này trái với các vị từ trong mệnh đề WHERE trong câu lệnh SELECT hoặc UPDATE.
KIỂM TRA và KIỂM TRA
Theo thời gian, logic kinh doanh thay đổi. Nó gây ra các sửa đổi đối tượng cơ sở dữ liệu. Hãy tưởng tượng một quốc gia mở rộng cơ sở mã zip và thêm các giá trị 6 chữ số.
Giá trị 5 chữ số cũ sẽ không còn được gán cho các khu vực. Tuy nhiên, chúng vẫn có giá trị đối với những cái hiện có. Do đó, ràng buộc CHECK phải tính đến dữ liệu hiện có ở định dạng cũ và xác thực dữ liệu ở định dạng mới.
Điều khoản NOCHECK giải quyết vấn đề này:
ALTER TABLE Customers WITH NOCHECK ADD CONSTRAINT CK_Zip_Code CHECK (Zip LIKE REPLICATE('[0-9]', 6)); GO
Chèn sau thành công:
INSERT INTO Customers (Customer_Id, Name, Status, Phone, State, Zip, Email, [Credit Limit]) VALUES (102, 'Jake Harrison', 'VIP', 555-555-1234, 'NY', 123456, '[email protected]', 100000); GO
Khi cố gắng chèn một mã zip gồm năm chữ số, động cơ sẽ xảy ra lỗi:
CHUỖI KIỂM TRA DBCC
Máy chủ SQL cung cấp CHUỖI KIỂM TRA DBCC để tìm kiếm dữ liệu không khớp với các ràng buộc.
Nếu có vấn đề về tính toàn vẹn của cơ sở dữ liệu, hãy chạy DBCC CHECKCONSTRAINTS cho toàn bộ cơ sở dữ liệu để đảm bảo không có sự cố nào.
Lưu ý rằng lệnh này ảnh hưởng đến hiệu suất. Do đó, nó sẽ không được chạy theo lịch trình.
Có thể chạy DBCC CHECKCONSTRAINTS cho một ràng buộc, một bảng hoặc toàn bộ cơ sở dữ liệu.
So với các lệnh kiểm tra khác, DBCC CHECKCONSTRAINTS cần thời gian đáng kể để hoàn thành và tiêu tốn tài nguyên hệ thống. Không giống như các lệnh khác, CHECKCONSTRAINTS không sử dụng ảnh chụp nhanh cơ sở dữ liệu.
Kết luận
Ràng buộc CHECK cung cấp cơ chế đánh giá dữ liệu trước khi chèn. Ràng buộc KIỂM TRA có thể tham chiếu đến một cột đơn hoặc nhiều cột trong bảng.
Các ràng buộc chỉ đơn giản là các vị từ dẫn đến TRUE, FALSE hoặc UNKNOWN. Trong trường hợp NULL được chèn vào bảng, một ràng buộc không bị vi phạm.