SQL Commands: DDL, DML, DCL and TCL Explained
On this page 10 sections ▾
SQL statements are grouped into four families, and the grouping is not academic trivia: it tells you whether a statement can be undone, whether it fires triggers, and whether running it quietly commits everything you had done before it.
This page defines each family, lists what belongs in it, and then covers the one consequence that catches people out in production. Where the in-browser engine can run an example it is runnable; where it cannot — permissions and transactions are not implemented in a single-tab database — the block is labelled rather than given a Run button that would only produce an error.
The four families at a glance
| Family | Stands for | Acts on | Main statements |
|---|---|---|---|
| DDL | Data Definition Language | the structure | CREATE, ALTER, DROP, TRUNCATE, RENAME |
| DML | Data Manipulation Language | the rows | INSERT, UPDATE, DELETE, MERGE |
| DCL | Data Control Language | permissions | GRANT, REVOKE |
| TCL | Transaction Control Language | units of work | COMMIT, ROLLBACK, SAVEPOINT, BEGIN |
Two notes before the detail. SELECT does not fit any of them cleanly — it reads without changing anything, and is sometimes given its own family, DQL (Data Query Language). And TRUNCATE is DDL despite feeling like a delete, which is exactly the kind of surprise the families are useful for predicting.
DDL: defining the structure
DDL creates, changes and removes the objects data lives in. CREATE makes one:
CREATE TABLE Suppliers (
supplier_id INT PRIMARY KEY,
name STRING NOT NULL,
country STRING
);
SELECT * FROM Suppliers;
● 0 rows · the query ran, and nothing in the sample database matched it
An empty table, with its shape defined. ALTER changes that shape afterwards:
ALTER TABLE Departments ADD COLUMN head STRING;
SELECT dept_id, dept_name FROM Departments;
| dept_id | dept_name |
|---|---|
| 10 | Engineering |
| 20 | Sales |
| 30 | Marketing |
| 40 | Support |
| 50 | Finance |
● 5 rows · produced by running this query on the sample database
DROP removes the object entirely, and TRUNCATE empties a table while keeping it — both covered in detail on the DELETE vs TRUNCATE vs DROP page, because choosing between them is a common interview question in its own right.
TRUNCATE TABLE Orders;
SELECT COUNT(*) AS orders_left FROM Orders;
| orders_left |
|---|
| 0 |
● 1 row · produced by running this query on the sample database
DML: changing the rows
DML is the family you use every day. INSERT adds rows:
INSERT INTO Departments (dept_id, dept_name, location, budget)
VALUES (60, 'Legal', 'Pune', 300000);
SELECT * FROM Departments;
| dept_id | dept_name | location | budget |
|---|---|---|---|
| 10 | Engineering | Bengaluru | 2400000 |
| 20 | Sales | London | 980000 |
| 30 | Marketing | New York | 640000 |
| 40 | Support | Berlin | 410000 |
| 50 | Finance | Singapore | 520000 |
| 60 | Legal | Pune | 300000 |
● 6 rows · produced by running this query on the sample database
UPDATE changes existing ones, and DELETE removes them — both taking a WHERE clause that decides which rows are affected:
UPDATE Products
SET unit_price = unit_price * 1.1
WHERE category = 'Accessories';
SELECT name, unit_price FROM Products WHERE category = 'Accessories';
| name | unit_price |
|---|---|
| Nimbus Docking Hub | 208.45 |
| Quill Keyboard | 130.9 |
● 2 rows · produced by running this query on the sample database
Because DML changes data rather than structure, it lives inside the transaction machinery: each change is logged, row triggers fire, and everything can be rolled back until it is committed. The changing data guide covers the habits that keep DML safe.
DCL: who is allowed to do what
Two statements, and they are the whole family. GRANT gives a permission and REVOKE takes it back:
GRANT SELECT ON Employees TO analyst;
REVOKE SELECT ON Employees FROM analyst;
Permissions in SQL are per-object and per-action, which is what makes least privilege practical: a reporting account can be granted SELECT on the tables it needs and nothing else, so a mistake in a report cannot delete anything. Roles group permissions so they can be granted once and assigned to many users.
This is the family that does not exist in the playground, and for a structural reason rather than a missing feature: the database here runs inside your own browser tab with no users, no accounts and nobody else to grant anything to.
TCL: committing and undoing work
A transaction is a group of statements that either all take effect or none do. TCL is how you mark the boundaries:
BEGIN TRANSACTION;
UPDATE Products SET unit_price = unit_price * 1.1
WHERE category = 'Accessories';
-- look at the result, then either keep it ...
COMMIT;
-- ... or undo everything since BEGIN with:
-- ROLLBACK;
SAVEPOINT adds partial undo inside a transaction: set one part-way through, and ROLLBACK TO SAVEPOINT name rewinds to that point without abandoning the whole transaction.
This is the safety net for a risky UPDATE
Open a transaction, run the UPDATE, SELECT the rows to check what happened, and only then COMMIT — or ROLLBACK if the count is wrong. It turns an irreversible mistake into a reversible one, which is why it is worth the two extra statements on anything that matters.
The consequence that actually bites: implicit commit
In several databases, including Oracle and MySQL, running a DDL statement commits the current transaction automatically, whether you wanted it to or not. So this sequence does not do what it looks like:
BEGIN TRANSACTION;
DELETE FROM Orders WHERE order_total < 2000;
CREATE TABLE audit_note (note STRING); -- DDL: implicit COMMIT here
ROLLBACK; -- too late, the DELETE is permanent
The CREATE TABLE committed the delete before the ROLLBACK was reached. PostgreSQL is the notable exception — it keeps DDL inside transactions, which is why migrations on PostgreSQL can be written as all-or-nothing scripts and migrations on MySQL generally cannot.
That single behaviour is why knowing which family a statement belongs to is worth the five minutes it takes to learn. Never mix DDL into a transaction you intend to be able to undo.
Sorting any statement into its family
- Does it change what the data means or where it lives? Structure → DDL.
- Does it change which rows exist or what they contain? Rows → DML.
- Does it change who can do something? Permissions → DCL.
- Does it mark the start or end of a unit of work? Transactions → TCL.
- Does it just read? SELECT — DQL, if your course insists on a name.
Applied to the two statements people most often place wrongly: TRUNCATE is DDL, because it deallocates storage rather than deleting rows one by one, and DELETE is DML, because it removes rows through the normal logged path.
Practice this topic
Reading explains the idea; producing it yourself is what makes it stick. These exercises use exactly what this page covers, and your answer is checked by running it against the same sample database:
- Look at the whole product catalogueEasy
- How many customers do we have?Easy
- Revenue actually shippedMedium
Frequently asked questions
What are DDL, DML, DCL and TCL in SQL?
They are the four families of SQL statements. DDL (Data Definition Language) defines structure with CREATE, ALTER, DROP and TRUNCATE. DML (Data Manipulation Language) changes rows with INSERT, UPDATE and DELETE. DCL (Data Control Language) manages permissions with GRANT and REVOKE. TCL (Transaction Control Language) marks units of work with COMMIT, ROLLBACK and SAVEPOINT.
Is TRUNCATE a DDL or DML command?
DDL. Although it removes rows, it does so by deallocating the storage they occupied rather than deleting them one at a time, which is also why it fires no row triggers, takes no WHERE clause, and in several databases cannot be rolled back.
Which SQL family does SELECT belong to?
Strictly none of the four, because it reads without changing anything. Many courses give it its own family, DQL - Data Query Language. In practice nobody is confused by calling SELECT a query.
What is an implicit commit?
Some databases, notably Oracle and MySQL, commit the current transaction automatically when a DDL statement runs. Anything you had done in that transaction becomes permanent at that moment, so a later ROLLBACK cannot undo it. PostgreSQL keeps DDL inside the transaction, which is why its migrations can be all-or-nothing.
Can DDL commands be rolled back?
It depends entirely on the database. PostgreSQL and SQL Server allow most DDL inside a transaction to be rolled back; Oracle and MySQL commit it immediately. Never rely on undoing a CREATE, ALTER or DROP without checking your specific database first.
What is the difference between DCL and TCL?
DCL controls who is permitted to do something - GRANT and REVOKE on tables, views and other objects. TCL controls when work becomes permanent - COMMIT, ROLLBACK and SAVEPOINT around a group of statements. One is about access, the other about durability.
Related reading
About the author
SQL Practice
SQL Practice publishes free SQL tutorials, an in-browser playground and 42 practice exercises, built so you can run what you read. Every runnable example in our tutorials is executed against the site’s sample database before it is published. Read how we keep tutorials accurate, or report a mistake.