Dòng phòng thủ đầu tiên để bảo vệ chống lại dữ liệu không hợp lệ xâm nhập vào các bảng của bạn là các loại dữ liệu của các cột.
Nếu một quá trình cố gắng chèn hoặc cập nhật một cột thành một giá trị nằm ngoài phạm vi của kiểu dữ liệu (hoặc NULL
nếu cột không cho phép NULL
s), thao tác sẽ thất bại ngay lập tức mà bạn không cần phải thực hiện thêm bất kỳ công việc nào.
Lựa chọn kiểu dữ liệu là một trong những khía cạnh quan trọng nhất của thiết kế bảng.
Vì vậy, vì bạn đã không đăng một lược đồ, tôi sẽ xây dựng một lược đồ dựa trên thông tin bạn đã cung cấp:
CREATE TABLE [dbo].[Tests]
(
ID int IDENTITY(1, 1) PRIMARY KEY,
Test_mode bit NOT NULL, /* Based on only seeing 0/1. Maybe tinyint? */
Active bit NULL
);
Dựa trên thiết kế này, các kết hợp có sẵn đã bị giới hạn ở những điều sau đây:
Test_mode hoạt động
0 NULL
0 0
0 1
1 NULL
1 0
1 1
Bất cứ điều gì khác hơn sẽ gây ra lỗi được nêu ra. (Đó là một điều tốt.)
Có cách nào để thay đổi giá trị của Test_mode thành 0 nếu 1 được chèn vào Active
HOẶC LÀ
Nếu Test_mode là 1 thì không cho phép chèn / cập nhật Active
HOẶC LÀ
Ném một số loại lỗi nếu Test_mode là 1 và cố gắng chèn / cập nhật Active.
Hoạt động chỉ có thể là NULL, 1, 0 và AND chỉ 1 với Test_mode là 0.
Bạn đã đưa ra 4 cách khác nhau để đi đến sự kết hợp các giá trị được phép (tốt, sắp xếp). Đây là những chiến lược rất khác nhau , với những hành vi thực hiện rất khác nhau.
Tôi thích sử dụng những gì được gọi là ràng buộc khai báo . Nói cách khác, lược đồ bảng và các đối tượng liên quan của nó giới hạn các giá trị được phép bằng cách khai báo rõ ràng những gì được phép (hoặc đôi khi, những gì không được phép). Trong thực tế, chính các kiểu dữ liệu cột là một loại ràng buộc khai báo. Càng gần với dữ liệu bảng, các giá trị có thể bị hạn chế, chúng càng dễ bị hạn chế và đáng tin cậy hơn. (Ngược lại, một ràng buộc không khai báo hoặc hoạt động sẽ được thực hiện bằng cách viết một đoạn T-SQL, thường là một trình kích hoạt bảng hoặc một phần của thủ tục được lưu trữ.)
3 tùy chọn đầu tiên chỉ có thể được thực hiện bằng các phương tiện không khai báo. Tuy nhiên, cái cuối cùng là khai báo, vì vậy hãy tập trung vào đó:
Active
chỉ có thể là NULL, 1, 0 và AND chỉ 1 với Test_mode
0.
Điều này xác định những gì bạn thực sự muốn, đó là sự kết hợp các giá trị được phép trong bảng. Lưu ý rằng các kết hợp hợp lệ chỉ phụ thuộc vào các giá trị cột trong cùng một hàng . Điều này rất quan trọng, vì nó xác định (các) cơ chế nào có thể được sử dụng để thực hiện các ràng buộc.
Trong trường hợp này, chúng ta có thể sử dụng một CHECK
hạn chế , đó là một / kiểm tra đúng sai quyết định xem một hàng là hợp lý hay không dựa trên một của hàng giá trị cột 1 . Nếu thử nghiệm thất bại, hoạt động cố gắng thay đổi hàng sẽ thất bại với một lỗi.
ALTER TABLE [dbo].[Tests] WITH CHECK
ADD CONSTRAINT CC_Tests_TestMode_Active
CHECK ((Test_mode != 0) OR ((Active IS NOT NULL) AND (Active = 1)));
Bạn sẽ lưu ý rằng tôi đã xây dựng vị từ sao cho nó sẽ tiếp tục hoạt động ngay cả khi Test_mode
thực sự là một kiểu số nguyên (không thể rỗng). Phần IS NOT NULL
này là bắt buộc vì các CHECK
ràng buộc cho phép các hàng trong đó vị từ ước tính undefined
.
1 Chúng có thể được sử dụng để kiểm tra bên ngoài hàng hiện tại, nhưng đây là một thực tiễn tồi và tôi sẽ không tham gia vào đó. Sử dụng một kích hoạt thay thế.