Reference

SQL Commands: DDL, DML, DCL and TCL Explained

7 min readUpdated September 10, 2026Every example verified
On this page 10 sections ▾
  1. The four families at a glance
  2. DDL: defining the structure
  3. DML: changing the rows
  4. DCL: who is allowed to do what
  5. TCL: committing and undoing work
  6. The consequence that actually bites: implicit commit
  7. Sorting any statement into its family
  8. Practice this topic
  9. Frequently asked questions
  10. Related reading

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

SQL command families
FamilyStands forActs onMain statements
DDLData Definition Languagethe structureCREATE, ALTER, DROP, TRUNCATE, RENAME
DMLData Manipulation Languagethe rowsINSERT, UPDATE, DELETE, MERGE
DCLData Control LanguagepermissionsGRANT, REVOKE
TCLTransaction Control Languageunits of workCOMMIT, 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_iddept_name
10Engineering
20Sales
30Marketing
40Support
50Finance

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_iddept_namelocationbudget
10EngineeringBengaluru2400000
20SalesLondon980000
30MarketingNew York640000
40SupportBerlin410000
50FinanceSingapore520000
60LegalPune300000

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';
nameunit_price
Nimbus Docking Hub208.45
Quill Keyboard130.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

  1. Does it change what the data means or where it lives? Structure → DDL.
  2. Does it change which rows exist or what they contain? Rows → DML.
  3. Does it change who can do something? Permissions → DCL.
  4. Does it mark the start or end of a unit of work? Transactions → TCL.
  5. 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:

See all 42 exercises →

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.

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.