MySQL Update
UPDATE changes existing rows. Like DELETE, a missing WHERE hits every row in the table. Same safety drill applies.
Single row
PHP
$stmt = $pdo->prepare(
'UPDATE customers SET email = ? WHERE id = ?'
);
$stmt->execute(['new@example.com', 42]);
echo $stmt->rowCount(); // 1 if found and changed, 0 otherwise
Multiple columns
PHP
$stmt = $pdo->prepare(
'UPDATE customers SET name = ?, email = ?, updated_at = NOW() WHERE id = ?'
);
$stmt->execute(['Ada Lovelace', 'ada@example.com', 42]);
Conditional bump
PHP
$pdo->prepare(
'UPDATE products SET stock = stock - 1 WHERE id = ? AND stock > 0'
)->execute([$productId]);
// the "AND stock > 0" stops the stock from going negative
Bulk-by-condition
PHP
$pdo->exec(
"UPDATE customers SET active = 0 WHERE last_login < NOW() - INTERVAL 1 YEAR"
);
Atomic increment vs read-modify-write
Read-modify-write is racy:
PHP
// ✗ Race: two requests both read stock=5, both write 4
$row = $pdo->query('SELECT stock FROM products WHERE id=42')->fetch();
$pdo->exec('UPDATE products SET stock = ' . ($row['stock'] - 1) . ' WHERE id = 42');
// ✓ Atomic — the DB handles concurrency
$pdo->prepare('UPDATE products SET stock = stock - 1 WHERE id = ? AND stock > 0')
->execute([42]);
Optimistic locking
If you must read first (to validate / show the user), check a version on update:
PHP
$stmt = $pdo->prepare(
'UPDATE customers SET email = ?, version = version + 1
WHERE id = ? AND version = ?'
);
$stmt->execute([$newEmail, $id, $oldVersion]);
if ($stmt->rowCount() === 0) {
throw new ConcurrencyException('Customer changed since you opened the form.');
}
Tip: Wrap related UPDATEs in a transaction. If you split "debit account A" and "credit account B" without one, a crash leaves the ledger out of balance.
Example
Example
<?php
$stmt = $pdo->prepare('UPDATE customers SET email = ? WHERE id = ?');
$stmt->execute(['new@example.com', 42]);
Try it Yourself »
Exercise
Atomic decrement keyword.
UPDATE products SET stock = stock
1 WHERE id = ?
A single character; subtract.
Discussion
Loading…