MySQL Delete
DELETE removes rows. Missing WHERE = empty table. Always dry-run with a SELECT first.
Single row
PHP
$stmt = $pdo->prepare('DELETE FROM customers WHERE id = ?');
$stmt->execute([42]);
echo $stmt->rowCount(), ' rows affected';
Multiple rows by condition
PHP
$stmt = $pdo->prepare(
'DELETE FROM logins WHERE created_at < ?'
);
$stmt->execute([(new DateTimeImmutable('-90 days'))->format('Y-m-d')]);
Safety patterns
- SELECT first. Same WHERE clause — make sure the row count looks right:
PHP
$stmt = $pdo->prepare('SELECT COUNT(*) FROM customers WHERE country = ?'); $stmt->execute(['XX']); echo $stmt->fetchColumn(), ' rows would be deleted'; - Wrap in a transaction. If something looks wrong, roll back:
PHP
$pdo->beginTransaction(); $stmt = $pdo->prepare('DELETE FROM customers WHERE country = ?'); $stmt->execute(['XX']); if ($stmt->rowCount() > 100) { $pdo->rollBack(); // too many — abort die('Aborted; check the WHERE'); } $pdo->commit(); - Soft delete. Many production schemas don't delete; they flag:
Queries then filterSQL
UPDATE customers SET deleted_at = NOW() WHERE id = 42;
WHERE deleted_at IS NULL.
Cascade behaviour
If customers has a foreign key from orders, a DELETE FROM customers may:
- RESTRICT — fail (default in InnoDB without ON DELETE).
- CASCADE — also delete the matching orders.
- SET NULL — null out the customer_id on orders.
Pick at table-create time with ON DELETE.
Tip: For data your users might want back (account, content), prefer soft delete and a scheduled hard-delete job after a cool-down period.
Example
Example
<?php
$stmt = $pdo->prepare('DELETE FROM customers WHERE id = ?');
$stmt->execute([42]);
echo $stmt->rowCount();
Try it Yourself »
Exercise
Always pair DELETE with…
DELETE FROM customers
id = 42
Five letters.
Discussion
Loading…