Skip to main content

Check Constraints

CHECK constraints let you encode business rules directly in schema.

That means bad values are rejected early, before they spread into application logic.

Core Concepts

flowchart TD
A[New row value] --> B[Evaluate CHECK expression]
B -->|True or NULL| C[Accept value]
B -->|False| D[Reject change]
Constraint ideaExample
Non-negative numericCHECK (price >= 0)
Range validationCHECK (age BETWEEN 0 AND 120)
Allowed setCHECK (status IN ('new','done'))

Code Examples

-- Add validation directly in table definition.
CREATE TABLE products (
product_id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price REAL NOT NULL CHECK (price >= 0),
stock INTEGER DEFAULT 0 CHECK (stock >= 0)
);
Expected output
Table created with CHECK constraints on price and stock.
-- Review stored CREATE statement including CHECK clauses.
SELECT sql
FROM sqlite_schema
WHERE type = 'table' AND name = 'products';
sql
CREATE TABLE products (... CHECK (price >= 0) ... CHECK (stock >= 0) ...)

SQLite-Specific Nuances

SQLite Nuance

In SQLite, a CHECK passes when expression result is true (non-zero) or NULL.

Use NOT NULL together with CHECK when nulls should be rejected.

Common Pitfalls / Best Practices

Pitfall

Writing complex CHECK expressions that are hard to read and maintain.

Hard-to-read constraints become hidden bugs later.

Best Practice

Prefer small, explicit checks (price >= 0, quantity >= 0) and compose multiple constraints when needed.

Quick Challenge

Create a reviews table where rating must be between 1 and 5.

View Solution
CREATE TABLE reviews (
review_id INTEGER PRIMARY KEY,
rating INTEGER NOT NULL CHECK (rating BETWEEN 1 AND 5),
comment TEXT
);
Expected output
Table is created with bounded rating validation.