Lesson 5 of 12

SQL INSERT, UPDATE and DELETE

Until now you have only read data. A real application also needs to save a new order, correct a price or remove a cancelled booking. Three statements do this work: SQL INSERT, UPDATE and DELETE. They are short and easy to learn, but they change data for real, so this lesson also covers how to use them carefully.

Tip: In our Try it editor the sample database is rebuilt every time you press Run, so you cannot break anything. Each example changes the data and then runs a SELECT so you can see the effect.

SQL INSERT: adding new rows

SQL INSERT INTO names the table and, in brackets, the columns you are filling. VALUES then lists the values in the same order. Text goes in single quotes; numbers do not.

INSERT INTO Customers (CustomerName, ContactName, City, State, Country, PostalCode)
VALUES ('Marina Traders', 'Revathi G', 'Chennai', 'Tamil Nadu', 'India', '600005');

SELECT CustomerID, CustomerName, City
FROM Customers
ORDER BY CustomerID DESC
LIMIT 3;

Returns 3 rows. The new customer appears at the top with CustomerID 13.

We did not give a CustomerID, yet the new row received 13. In SQLite, a column declared INTEGER PRIMARY KEY is filled automatically with the next number. MySQL does the same with AUTO_INCREMENT, and SQL Server with IDENTITY. You will create such columns yourself in SQL CREATE TABLE.

Columns you leave out get their default value, or NULL if there is no default. You could skip the column list and write only VALUES (…), but then you must supply every column in the exact table order. Listing the columns is safer and keeps working if the table changes later.

Inserting several rows at once

Separate each row’s values with a comma. This is faster than running many single inserts, and SQLite (since 3.7.11), MySQL and SQL Server all support it.

INSERT INTO Products (ProductName, CategoryID, Unit, Price)
VALUES ('Cumin Seeds', 5, '100 g pack', 65),
       ('Cloves', 5, '50 g pack', 140);

SELECT ProductID, ProductName, Price
FROM Products
WHERE CategoryID = 5;

Returns 5 spice products, including the new Cumin Seeds (ID 16) and Cloves (ID 17).

UPDATE: changing existing rows

UPDATE names the table, SET gives the new values, and WHERE decides which rows change. The new value can use the old one, as in Price = Price * 1.10 for a 10% rise. To change several columns, separate them with commas: SET Status = 'Delivered', OrderDate = '2026-03-05'.

UPDATE Products
SET Price = ROUND(Price * 1.10, 2)
WHERE CategoryID = 5;

SELECT ProductName, Price
FROM Products
WHERE CategoryID = 5;

Returns 3 rows: Turmeric Powder 77, Black Pepper 132, Cardamom 231.

We wrapped the calculation in ROUND() because decimal maths on computers is not exact: 210 * 1.10 comes out as 231.00000000000003. For money, many MySQL projects use the DECIMAL type, which stores exact values. SQLite has no exact decimal type, so apps often store paise as whole numbers instead.

Watch out: An UPDATE or DELETE without WHERE affects every row in the table. UPDATE Products SET Price = 0; makes every product free. Before running a change, write the same WHERE in a SELECT first and check that it returns only the rows you expect.

DELETE: removing rows

DELETE FROM removes whole rows that match the WHERE condition. You cannot delete a single column value this way – for that, use UPDATE and set it to NULL.

Related rows matter. Order 1005 was cancelled, and it has a line in OrderDetails. If we delete only the order, that line is left pointing at an order that no longer exists. So we delete the child rows first, then the order itself:

DELETE FROM OrderDetails WHERE OrderID = 1005;
DELETE FROM Orders WHERE OrderID = 1005;

SELECT OrderID, CustomerID, Status
FROM Orders;

Returns 9 orders. Order 1005 (the cancelled one) is gone.

Foreign key constraints can stop you from leaving such orphan rows, or delete them for you automatically. That is covered in SQL Constraints and Keys. MySQL and SQL Server also have TRUNCATE TABLE for emptying a table quickly; SQLite does not, but DELETE FROM table; with no WHERE does the same job.

Undoing mistakes with transactions

A transaction groups statements so they either all happen or none do. Start one with BEGIN. If everything looks right, finish with COMMIT; if not, ROLLBACK cancels every change since BEGIN. In the example below the delete is rolled back, so all eight employees are still there.

BEGIN;
DELETE FROM Employees WHERE Department = 'Support';
ROLLBACK;

SELECT FirstName, Department
FROM Employees;

Returns all 8 employees, including Fathima from Support, because the DELETE was rolled back.

Transactions are also how a shop app makes sure an order and its order lines are saved together. MySQL’s default InnoDB engine supports them in the same way, using START TRANSACTION or BEGIN.

From SQL to a real website

In a PHP site you never paste user input straight into these statements. You use prepared statements with placeholders, which you will see in PHP MySQL with PDO. Next in this track, SQL Aggregate Functions shows how to count and total your data. To review sorting first, go back to SQL ORDER BY and LIMIT.

Further reading

Key takeaways

  • INSERT INTO table (columns) VALUES (values) adds rows; list several value groups to add many rows.
  • INTEGER PRIMARY KEY in SQLite (AUTO_INCREMENT in MySQL) fills the ID for you.
  • UPDATE … SET … WHERE … changes existing rows; the new value can use the old one.
  • DELETE FROM … WHERE … removes rows; delete child rows before their parent.
  • Without WHERE, UPDATE and DELETE affect every row – test the WHERE with SELECT first.
  • BEGIN, COMMIT and ROLLBACK let you group changes and undo them.

Quick quiz

Check what you learned – pick an answer.

1. What happens when you run UPDATE Employees SET Salary = 50000; ?

2. Which statement removes order 1009 from the Orders table?

3. After BEGIN; DELETE FROM Products; ROLLBACK; how many products are left?

Practice exercise

Order 1009 has now been shipped. Change its Status to 'Shipped', then show OrderID and Status for that order.

Show a hint

Use UPDATE with WHERE OrderID = 1009, then a SELECT with the same WHERE.

Show the solution
UPDATE Orders
SET Status = 'Shipped'
WHERE OrderID = 1009;

SELECT OrderID, Status
FROM Orders
WHERE OrderID = 1009;

Progress is saved in this browser only.