Why Push Business Rules Into Your SQL Server Schema, Not Just the App
Constraints aren’t just data hygiene — they’re how you encode real business rules directly into the schema, so they can never be silently bypassed by a buggy application, a second app added later that talks to the same database, or a stray ad-hoc UPDATE run during an incident.
Encoding a Real Rule
-- Rule: an order's ship date can never be before its order date
CREATE TABLE dbo.CustomerOrder (
order_id INT IDENTITY(1,1) PRIMARY KEY,
order_date DATE NOT NULL,
ship_date DATE NULL
CHECK (ship_date IS NULL OR ship_date >= order_date),
total_usd DECIMAL(10,2) NOT NULL CHECK (total_usd >= 0)
);
-- Proving the rule holds, not just reading about it:
INSERT INTO dbo.CustomerOrder (order_date, ship_date, total_usd) VALUES ('2026-01-10', '2026-01-05', 49.99);
-- Error: CHECK constraint violated — shipped 5 days BEFORE it was ordered, correctly rejected
A CHECK Constraint Spanning Multiple Columns
CHECK isn’t limited to validating one column against a literal — it can compare columns on the same row to each other, as shown above (ship_date against order_date). Another common shape:
CREATE TABLE dbo.Promotion (
promotion_id INT IDENTITY(1,1) PRIMARY KEY,
starts_on DATE NOT NULL,
ends_on DATE NOT NULL,
CHECK (ends_on > starts_on)
);
This kind of cross-column rule is exactly the class of business logic that’s easy to forget to validate in one code path of an application (a bulk-import script, an admin panel, an API endpoint added six months later by someone unfamiliar with the original rule) but structurally impossible to skip once it lives in the schema.
The Last Line of Defense
Applications get replaced, have bugs, or get bypassed by a direct database script during an incident. A CHECK constraint at the database layer is enforced no matter what wrote the data — it’s the guarantee application code alone can never fully provide. This is sometimes summarized as “defense in depth”: validate in the application for a fast, friendly error message to the user, and validate in the database as the guarantee that actually holds under all circumstances.
Where This Doesn’t Reach — And What Does
CHECK constraints are limited to logic expressible within a single row’s own columns — they can’t reference other tables or aggregate across rows. “A department can’t have more than 20 staff” or “an order’s total must match the sum of its line items” needs a different tool: a trigger, or logic in a stored procedure. That’s a deliberate scope boundary you’ll meet by name (constraints vs. triggers vs. procedures) as a full decision framework in SQL Server for Developers & DBAs — for now, the key lesson is simply that single-row rules belong in CHECK constraints, full stop, because nothing enforces them more reliably.
Enjoyed this?
Subscribe to get every new SQL Server lesson as soon as it’s published, and share it with a developer who’d find it useful.
📡 Subscribe via RSS |
Share on X |
Share on LinkedIn |
Share on Facebook
Want the full structured course with quizzes, projects, and 10+ exercises per chapter? Check out SQL Server Fundamentals, coming soon on this site.