CRUD Operations
Difficulty: Beginner · ~10 min read
Overview
CRUD stands for Create, Read, Update, Delete — the four basic operations every database supports:
| Operation | SQL keyword | Purpose |
|---|---|---|
| Create | INSERT |
Add new rows |
| Read | SELECT |
Query existing rows |
| Update | UPDATE |
Modify existing rows |
| Delete | DELETE |
Remove rows |
DB2 also supports a fifth, very useful operation: MERGE, which combines insert + update ("upsert") in one statement.
Syntax
-- INSERT
INSERT INTO table_name (col1, col2, ...) VALUES (val1, val2, ...);
-- SELECT
SELECT col1, col2 FROM table_name WHERE condition FETCH FIRST n ROWS ONLY;
-- UPDATE
UPDATE table_name SET col1 = val1 WHERE condition;
-- DELETE
DELETE FROM table_name WHERE condition;
-- MERGE (upsert)
MERGE INTO target USING source ON match_condition
WHEN MATCHED THEN UPDATE SET ...
WHEN NOT MATCHED THEN INSERT (...) VALUES (...);
Examples
We'll use a products table throughout:
CREATE TABLE products (
product_id INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(80) NOT NULL,
category VARCHAR(40),
price DECIMAL(9,2) NOT NULL,
stock INTEGER NOT NULL DEFAULT 0
);
Example 1: INSERT — single, multi-row, and from SELECT
-- Single row
INSERT INTO products VALUES (1, 'Widget', 'Hardware', 9.99, 100);
-- Multiple rows in one statement
INSERT INTO products (product_id, name, category, price, stock) VALUES
(2, 'Gadget', 'Hardware', 14.50, 50),
(3, 'Sprocket','Hardware', 3.25, 200),
(4, 'Manual', 'Books', 19.99, 25);
-- Insert from another query
INSERT INTO products_archive (product_id, name, price)
SELECT product_id, name, price
FROM products
WHERE stock = 0;
Example 2: SELECT — the basics + DB2-specific pagination
-- All columns
SELECT * FROM products;
-- Specific columns with filtering and ordering
SELECT name, price
FROM products
WHERE category = 'Hardware'
AND price < 10
ORDER BY price DESC;
-- DB2 pagination (top 2 most expensive)
SELECT name, price
FROM products
ORDER BY price DESC
FETCH FIRST 2 ROWS ONLY;
Output:
NAME PRICE
-------- ------
Manual 19.99
Gadget 14.50
DB2 uses FETCH FIRST n ROWS ONLY (standard SQL), not LIMIT (MySQL/Postgres) or TOP n (SQL Server).
Example 3: UPDATE — single and conditional
-- Bump all hardware prices by 10%
UPDATE products
SET price = price * 1.10
WHERE category = 'Hardware';
-- Set stock to 0 for a specific product
UPDATE products
SET stock = 0
WHERE product_id = 3;
-- Update multiple columns at once
UPDATE products
SET (price, stock) = (29.99, 10)
WHERE product_id = 4;
Example 4: DELETE
-- Delete a single row
DELETE FROM products WHERE product_id = 3;
-- Delete with a subquery
DELETE FROM products
WHERE category IN (SELECT category FROM discontinued_categories);
-- Delete everything (use with extreme caution — no rollback after COMMIT!)
DELETE FROM products;
Example 5: MERGE — upsert in one shot
MERGE INTO products AS p
USING (VALUES (1, 'Widget v2', 'Hardware', 12.00, 75)) AS s(id, name, cat, price, stock)
ON p.product_id = s.id
WHEN MATCHED THEN
UPDATE SET p.name = s.name, p.price = s.price, p.stock = s.stock
WHEN NOT MATCHED THEN
INSERT (product_id, name, category, price, stock)
VALUES (s.id, s.name, s.cat, s.price, s.stock);
If product 1 exists → it gets updated. If not → it gets inserted.
Example 6: SELECT with aggregation
SELECT category,
COUNT(*) AS num_items,
SUM(stock) AS total_stock,
AVG(price) AS avg_price
FROM products
GROUP BY category
HAVING COUNT(*) > 1
ORDER BY category;
Notes & Tips
- Always
COMMITwhen running statements through thedb2CLP unless you haveAUTOCOMMIT ON(the default in many clients). Otherwise your changes will be rolled back when the session ends. - The
FETCH FIRST n ROWS ONLYclause replaces the olderOPTIMIZE FOR n ROWS— useFETCH FIRSTin new code. - DB2 supports
OFFSET n ROWS FETCH FIRST m ROWS ONLYfor paging since v11.1. - For
UPDATE/DELETEwithout aWHERE, DB2 will touch every row. Get into the habit of writing theWHEREfirst. INSERT … SELECTis the most efficient way to copy data between tables — much faster than row-by-row.- DB2 supports the
RETURNINGclause inside aSELECT FROM FINAL TABLE (UPDATE …)— see Example below.
-- Get the updated rows in the same statement
SELECT product_id, price
FROM FINAL TABLE (UPDATE products SET price = price * 1.10 WHERE category = 'Hardware');
Practice Exercises
- Insert three rows into a
customerstable you create. Each row should use theCURRENT_TIMESTAMPdefault for acreated_atcolumn. - Increase every customer's
loyalty_pointsby 5%, but only for customers whoseregion = 'EU'. - Write a
MERGEthat inserts a customer if theiremailis new, or updates theirnameif the email already exists. - Use
FETCH FIRST 5 ROWS ONLYto return the 5 most recent customers. - Use
SELECT … FROM FINAL TABLE (DELETE …)to delete and inspect the deleted rows in one statement.
Quick Quiz
Q1. Which DB2 clause limits the number of rows returned (replaces LIMIT / TOP)?
Show answer
FETCH FIRST n ROWS ONLY. It's the SQL standard form. Since DB2 11.1 you can also combine it with OFFSET n ROWS for pagination.
Q2. What does MERGE do that INSERT and UPDATE alone can't?
Show answer
MERGE is an upsert — it inspects a join condition and runs UPDATE if a matching row exists, or INSERT if it doesn't, all in one atomic statement. Without MERGE you'd need an explicit SELECT + branching logic.
Q3. What happens if you run DELETE FROM products with no WHERE clause?
Show answer
Every row in the products table is deleted. The table itself still exists (use DROP TABLE to remove the schema). Always double-check before running unfiltered DML — and use a transaction so you can ROLLBACK.
Next Up
CRUD lets you change data — next we add constraints so the database refuses changes that would break our rules.