Ràng buộc CHECK trong SQL Server

Trong hướng dẫn này, bạn sẽ học cách sử dụng ràng buộc CHECK trong SQL Server để giới hạn các giá trị có thể được insert hoặc update vào một hoặc nhiều cột trong bảng.

Giới thiệu về ràng buộc CHECK trong SQL Server

Ràng buộc CHECK trong SQL Server cho phép bạn chỉ định các giá trị trong một cột phải đáp ứng một biểu thức Boolean.

Ví dụ: để yêu cầu đơn giá lớn hơn 0, bạn có thể sử dụng:

CREATE SCHEMA test;
GO

CREATE TABLE test.products(
    product_id INT IDENTITY PRIMARY KEY,
    product_name VARCHAR(255) NOT NULL,
    unit_price DEC(10,2) CHECK(unit_price > 0)
);

Như bạn có thể thấy, CHECK định nghĩa ràng buộc nằm sau kiểu dữ liệu. Nó bao gồm từ khóa CHECK theo sau là một biểu thức logic trong dấu ngoặc đơn:

CHECK(unit_price > 0)

Bạn cũng có thể gán cho ràng buộc một tên riêng bằng cách sử dụng từ khóa CONSTRAINT như sau:

CREATE TABLE test.products(
    product_id INT IDENTITY PRIMARY KEY,
    product_name VARCHAR(255) NOT NULL,
    unit_price DEC(10,2) CONSTRAINT positive_price CHECK(unit_price > 0)
);

Chỉ định tên ràng buộc rõ ràng giúp phân loại các thông báo lỗi và cho phép bạn tham chiếu đến các ràng buộc khi bạn muốn sửa đổi chúng.

Nếu bạn không chỉ định tên ràng buộc theo cách này, SQL Server sẽ tự động tạo tên cho bạn.

Xem câu lệnh insert sau:

INSERT INTO test.products(product_name, unit_price)
VALUES ('Awesome Free Bike', 0);

SQL Server sẽ thông báo lỗi sau:

The INSERT statement conflicted with the CHECK constraint "positive_price". The conflict occurred in database "BikeStores", table "test.products", column 'unit_price'.

Lỗi xảy ra do đơn giá không lớn hơn 0 như được chỉ định trong ràng buộc CHECK.

Câu lệnh sau hoạt động tốt vì biểu thức logic được xác định trong ràng buộc CHECK đánh giá là TRUE:

INSERT INTO test.products(product_name, unit_price)
VALUES ('Awesome Bike', 599);

Ràng buộc CHECK và NULL trong SQL Server

Ràng buộc CHECK từ chối các giá trị gây ra biểu thức Boolean được đánh giá FALSE.

NULL đánh giá thành UNKNOWN, nó có thể được sử dụng trong biểu thức để bỏ qua một ràng buộc.

Ví dụ: bạn có thể insert một sản phẩm có đơn giá NULL như được hiển thị trong truy vấn sau:

INSERT INTO test.products(product_name, unit_price)
VALUES ('Another Awesome Bike', NULL);

Đây là kết quả:

(1 row affected)

SQL Server đã chèn NULL vào cột unit_price và không trả lại lỗi.

Để khắc phục điều này, bạn cần sử dụng một ràng buộc NOT NULL cho cột unit_price.

Ràng buộc CHECK tham chiếu đến nhiều cột

Một ràng buộc CHECK có thể tham chiếu đến nhiều cột. Ví dụ: bạn lưu trữ giá thông thường và giá chiết khấu trong  bảng test.products và bạn muốn đảm bảo rằng giá chiết khấu luôn thấp hơn giá thông thường:

CREATE TABLE test.products(
    product_id INT IDENTITY PRIMARY KEY,
    product_name VARCHAR(255) NOT NULL,
    unit_price DEC(10,2) CHECK(unit_price > 0),
    discounted_price DEC(10,2) CHECK(discounted_price > 0),
    CHECK(discounted_price < unit_price)
);

Hai ràng buộc đầu tiên cho unit_pricediscounted_price nên trông quen thuộc.

Ràng buộc thứ ba sử dụng một cú pháp mới không được gắn vào một cột cụ thể. Thay vào đó, nó xuất hiện dưới dạng một hàng riêng biệt trong danh sách cột được phân tách bằng dấu phẩy.

Ràng buộc hai cột đầu tiên là ràng buộc cột, trong khi ràng buộc thứ ba là ràng buộc bảng.

Lưu ý: bạn có thể viết các ràng buộc cột dưới dạng các ràng buộc bảng. Tuy nhiên, bạn không thể viết ràng buộc bảng dưới dạng ràng buộc cột. Ví dụ, bạn có thể viết lại câu lệnh trên như sau:
CREATE TABLE test.products(
    product_id INT IDENTITY PRIMARY KEY,
    product_name VARCHAR(255) NOT NULL,
    unit_price DEC(10,2),
    discounted_price DEC(10,2),
    CHECK(unit_price > 0),
    CHECK(discounted_price > 0),
    CHECK(discounted_price > unit_price)
);

hoặc thậm chí:

CREATE TABLE test.products(
    product_id INT IDENTITY PRIMARY KEY,
    product_name VARCHAR(255) NOT NULL,
    unit_price DEC(10,2),
    discounted_price DEC(10,2),
    CHECK(unit_price > 0),
    CHECK(discounted_price > 0 AND discounted_price > unit_price)
);

Bạn cũng có thể gán tên cho một ràng buộc bảng theo cách giống như một ràng buộc cột:

CREATE TABLE test.products(
    product_id INT IDENTITY PRIMARY KEY,
    product_name VARCHAR(255) NOT NULL,
    unit_price DEC(10,2),
    discounted_price DEC(10,2),
    CHECK(unit_price > 0),
    CHECK(discounted_price > 0),
    CONSTRAINT valid_prices CHECK(discounted_price > unit_price)
);

Thêm ràng buộc CHECK vào bảng hiện có

Để thêm một ràng buộc CHECK vào một bảng hiện có, bạn sử dụng câu lệnh ALTER TABLE ADD CONSTRAINT.

Giả sử bạn có bảng test.products sau:

CREATE TABLE test.products(
    product_id INT IDENTITY PRIMARY KEY,
    product_name VARCHAR(255) NOT NULL,
    unit_price DEC(10,2) NOT NULL
);

Để thêm một ràng buộc CHECK vào bảng test.products, bạn sử dụng câu lệnh sau:

ALTER TABLE test.products
ADD CONSTRAINT positive_price CHECK(unit_price > 0);

Để thêm một cột mới với một ràng buộc CHECK, bạn sử dụng câu lệnh sau:

ALTER TABLE test.products
ADD discounted_price DEC(10,2)
CHECK(discounted_price > 0);

Để thêm một ràng buộc CHECK có tên valid_price, bạn sử dụng câu lệnh sau:

ALTER TABLE test.products
ADD CONSTRAINT valid_price 
CHECK(unit_price > discounted_price);

Xóa ràng buộc CHECK trong SQL Server

Để xóa một ràng buộc CHECK, bạn sử dụng câu lệnh ALTER TABLE DROP CONSTRAINT:

ALTER TABLE table_name
DROP CONSTRAINT constraint_name;

Nếu bạn gán cho một ràng buộc CHECK một tên cụ thể, bạn có thể tham chiếu tên đó trong câu lệnh.

Tuy nhiên, trong trường hợp bạn không gán cho ràng buộc CHECK một tên cụ thể, thì bạn cần phải tìm nó bằng cách sử dụng câu lệnh sau:

EXEC sp_help 'table_name';

Ví dụ:

EXEC sp_help 'test.products';

Câu lệnh này đưa ra rất nhiều thông tin bao gồm các tên ràng buộc:

Xóa ràng buộc CHECK trong SQL Server

Câu lệnh sau xóa ràng buộc positive_price:

ALTER TABLE test.products
DROP CONSTRAINT positive_price;

Tắt ràng buộc CHECK để INSERT hoặc UPDATE

Để vô hiệu hóa một ràng buộc CHECK cho việc insert hoặc update, bạn sử dụng câu lệnh sau:

ALTER TABLE table_name
NOCHECK CONSTRAINT constraint_name;

Câu lệnh sau vô hiệu hóa ràng buộc valid_price:

ALTER TABLE test.products
NO CHECK CONSTRAINT valid_price;

Trong hướng dẫn này, bạn đã học cách sử dụng ràng buộc CHECK trong SQL Server để giới hạn các giá trị có thể được insert hoặc update vào một hoặc nhiều cột trong bảng.

SQL Server
Bài Viết Liên Quan:
Sequence trong SQL Server
Trung Nguyen 31/07/2021
Sequence trong SQL Server

Trong hướng dẫn này, bạn sẽ tìm hiểu về các đối tượng Sequence trong SQL Server để tạo ra một chuỗi các giá trị số dựa trên một đặc tả cụ thể.

Cột Identity trong SQL Server
Trung Nguyen 30/07/2021
Cột Identity trong SQL Server

Trong hướng dẫn này, bạn sẽ học cách sử dụng thuộc tính IDENTITY trong SQL Server để thêm cột định danh vào bảng.

CREATE TABLE trong SQL Server
Trung Nguyen 29/07/2021
CREATE TABLE trong SQL Server

Trong hướng dẫn này, bạn sẽ học cách sử dụng câu lệnh CREATE TABLE trong SQL Server để tạo một bảng mới.

Ràng buộc NOT NULL trong SQL Server
Trung Nguyen 28/07/2021
Ràng buộc NOT NULL trong SQL Server

Trong hướng dẫn này, bạn sẽ học cách sử dụng ràng buộc NOT NULL trong SQL Server để đảm bảo một cột không chứa dữ liệu NULL.