SQL Quest
Sign in Français 0 XP Lvl 1
Intermediate

SQL INSERT, UPDATE and DELETE: change the data

5 min read · 3 runnable examples · updated October 9, 2026

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

produits (before)
nomcategorieprix
Guide SQLLivres20
PlaidMaison25
BD aventureLivres10
produits (after)
nomcategorieprix
Guide SQLLivres22
PlaidMaison25
BD aventureLivres11
UPDATE produits SET prix = prix * 1.1 WHERE categorie = 'Livres': only the rows matching the WHERE are changed.

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
Result
idnompays
1TechNovaFrance
2ElectroPlusAllemagne
3MaisonDecoFrance
4SportZoneEspagne
5BookWorldBelgique
6GreenFoodItalie
7AsiaPartsChine
8NordicHomeSuè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
Result
nomprix
Roman policier8.83
Guide SQL27.78
BD aventure10.98
Livre de cuisine20.54
Manga tome 131.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
Result
statutnb
en cours109
expédiée93
livrée306

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.

Avoid
UPDATE produits SET stock = 0;
Correct
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.

Avoid
INSERT INTO fournisseurs (id, nom, pays) VALUES (9, 'Test');
Correct
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.

Avoid
INSERT INTO fournisseurs (id, nom, pays) VALUES (1, 'Doublon', 'France');
Correct
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;
nomstock
Haltères 5kg0
Corde à sauter0
Manga tome 10

3 rows in total

Try it in the sandbox

Challenge 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 sandbox
Want more practice?

The interactive exercises are checked automatically, with a tutor who explains your mistakes. A short lesson stays next to the editor.

Do the interactive exercises

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.

Read next