SQL INSERT, UPDATE and DELETE: change the data
So far, every query read data without changing anything. Three statements let you change it: INSERT adds rows, UPDATE changes existing values and DELETE removes rows. They are powerful… and dangerous: a forgotten condition can change a whole table at once.
Syntax
INSERT INTO table (col1, col2) VALUES (value1, value2);
UPDATE table SET col1 = value WHERE condition;
DELETE FROM table WHERE condition;How it works
INSERT: add rows
List the columns to fill, then the values in the same order. Columns you leave out get their default value, or NULL. You can insert several rows at once: VALUES (…), (…), (…).
UPDATE: change rows
SET gives the new values, possibly computed from the old ones (prix = prix * 1.1). The WHERE says which rows to change. Without WHERE, every row of the table is changed.
DELETE: remove rows
Same caution: without WHERE, the whole table is emptied. When rows reference others (an order line points to its order), delete the “child” rows first.
The good habit
Before an UPDATE or a DELETE, run a SELECT with the same WHERE: you see exactly which rows will be affected. In a real application, changes are grouped in a transaction (BEGIN … COMMIT), which can be cancelled with ROLLBACK if something goes wrong.
Diagram
| nom | categorie | prix |
|---|---|---|
| Guide SQL | Livres | 20 |
| Plaid | Maison | 25 |
| BD aventure | Livres | 10 |
| nom | categorie | prix |
|---|---|---|
| Guide SQL | Livres | 22 |
| Plaid | Maison | 25 |
| BD aventure | Livres | 11 |
Simplified diagram to show the idea. The examples below use the real SQL Quest practice database (a fictional online shop: see the full schema).
Glossary: the sample database uses French names
clients- customers
commandes- orders
lignes_commande- order lines
produits- products
fournisseurs- suppliers
employes- employees
prenom / nom- first name / last name (or name)
ville- city
pays- country
prix- price
prix_unitaire- unit price
quantite- quantity
categorie- category
date_commande- order date
poste- job title
departement- department
salaire- salary
statut- status: livrée = delivered, expédiée = shipped, en cours = in progress, annulée = cancelled
Examples with their results
1. Add a row
Add a supplier, then show the table to check. (The examples on this page run on a copy of the database.)
INSERT INTO fournisseurs (id, nom, pays)
VALUES (8, 'NordicHome', 'Suède');
SELECT * FROM fournisseurs; Try it in the sandbox| id | nom | pays |
|---|---|---|
| 1 | TechNova | France |
| 2 | ElectroPlus | Allemagne |
| 3 | MaisonDeco | France |
| 4 | SportZone | Espagne |
| 5 | BookWorld | Belgique |
| 6 | GreenFood | Italie |
| 7 | AsiaParts | Chine |
| 8 | NordicHome | Suède |
8 rows in total
2. Change rows
Raise the price of books (Livres) by 10%, then check.
UPDATE produits
SET prix = ROUND(prix * 1.1, 2)
WHERE categorie = 'Livres';
SELECT nom, prix FROM produits WHERE categorie = 'Livres'; Try it in the sandbox| nom | prix |
|---|---|
| Roman policier | 8.83 |
| Guide SQL | 27.78 |
| BD aventure | 10.98 |
| Livre de cuisine | 20.54 |
| Manga tome 1 | 31.81 |
5 rows in total
3. Delete related rows
Delete the cancelled orders and their order lines (the “child” rows first), then count what is left.
DELETE FROM lignes_commande
WHERE commande_id IN (SELECT id FROM commandes WHERE statut = 'annulée');
DELETE FROM commandes WHERE statut = 'annulée';
SELECT statut, COUNT(*) AS nb FROM commandes GROUP BY statut; Try it in the sandbox| statut | nb |
|---|---|
| en cours | 109 |
| expédiée | 93 |
| livrée | 306 |
3 rows in total
Common mistakes
UPDATE or DELETE without WHERE
It is the most expensive mistake in SQL: every row is changed or deleted, without any confirmation.
UPDATE produits SET stock = 0;UPDATE produits SET stock = 0 WHERE id = 3;A number of values different from the number of columns
INSERT requires as many values as listed columns, in the same order.
INSERT INTO fournisseurs (id, nom, pays) VALUES (9, 'Test');INSERT INTO fournisseurs (id, nom, pays) VALUES (9, 'Test', 'France');Inserting an id that already exists
A primary key must be unique: SQLite answers UNIQUE constraint failed. Let the database choose the id, or pick a free one.
INSERT INTO fournisseurs (id, nom, pays) VALUES (1, 'Doublon', 'France');INSERT INTO fournisseurs (nom, pays) VALUES ('Nouveau', 'France');Exercises
Try writing the query yourself before opening the solution.
Challenge 1. Set the stock to 0 for the products whose supplier is based in China (Chine), then show those products.
Show a solution
UPDATE produits SET stock = 0 WHERE fournisseur_id IN (SELECT id FROM fournisseurs WHERE pays = 'Chine');
SELECT nom, stock FROM produits WHERE stock = 0;| nom | stock |
|---|---|
| Haltères 5kg | 0 |
| Corde à sauter | 0 |
| Manga tome 1 | 0 |
3 rows in total
Try it in the sandboxChallenge 2. Add two customers in a single INSERT query, then count the customers.
Show a solution
INSERT INTO clients (prenom, nom, ville) VALUES ('Nina', 'Petit', 'Lyon'), ('Paul', 'Morel', 'Nice');
SELECT COUNT(*) FROM clients;| COUNT(*) |
|---|
| 122 |
1 row in total
Try it in the sandboxThe interactive exercises are checked automatically, with a tutor who explains your mistakes. A short lesson stays next to the editor.
Frequently asked questions
How do I undo an UPDATE or a DELETE?
Only if it was done in a transaction that has not been committed (BEGIN … ROLLBACK). Once committed, the change is permanent: hence the value of backups and of running a SELECT first to check.
What is the difference between DELETE and DROP TABLE?
DELETE removes rows but keeps the table. DROP TABLE removes the whole table, structure included.
Can I change several columns in one UPDATE?
Yes: UPDATE produits SET prix = 19.9, stock = 50 WHERE id = 3.
How do I get the id of a row I just inserted?
In SQLite, with last_insert_rowid() or the RETURNING id clause (since version 3.35). PostgreSQL also offers RETURNING.