SQL CHECK
CHECK rejects rows where a boolean expression is false. It lets you enforce domain rules without writing a trigger or relying on app code.
Column-level CHECK
SQL
CREATE TABLE products ( id INT PRIMARY KEY, price DECIMAL(10,2) CHECK (price >= 0), stock INT CHECK (stock >= 0) );
Table-level CHECK (can reference multiple columns)
SQL
CREATE TABLE bookings ( id INT PRIMARY KEY, start_at DATETIME, end_at DATETIME, CONSTRAINT chk_dates CHECK (end_at > start_at) );
Add or drop later
SQL
ALTER TABLE products ADD CONSTRAINT chk_price CHECK (price >= 0); ALTER TABLE products DROP CONSTRAINT chk_price;
CHECK and NULL
A check passes when the expression is TRUE or NULL — only an explicit FALSE rejects the row. CHECK (price >= 0) allows price = NULL. Combine with NOT NULL if you want both.
MySQL note
MySQL accepted CHECK syntax for years without enforcing it. As of MySQL 8.0.16+ it does. Older MariaDB versions may still ignore them — check your server.
Tip: Use CHECK to encode invariants that have no business changing — non-negative prices, valid statuses (
CHECK (status IN ('pending','paid','cancelled'))). Anything that changes per business request belongs in app code.Example
Exercise
Disallow negative prices.
(price >= 0)
Five letters; rule constraint.
Discussion
Loading…