# ch06 — UPDATE と DELETE

Source: https://php-school.pages.dev/topics/db/ch06-update-delete/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: データベース連携
Level: L4

Reference (official): https://www.php.net/manual/ja/book.pdo.php

## 本文

# ch06 — UPDATE と DELETE

## 概要

既存行の **書き換え** と **削除** を担うのが `UPDATE` と `DELETE`。書き換えは `UPDATE users SET age = ? WHERE id = ?`、削除は `DELETE FROM users WHERE id = ?` で、`SET` で更新内容、`WHERE` で対象範囲を指定。値の埋め込みは `prepare` + `execute` の組み合わせ。

実行後の **結果確認** は `fetchAll()` ではなく **`$stmt->rowCount()`** で「影響を受けた行数」を取る。`1` なら期待通り 1 件更新、`0` なら該当行が無くて何も変わっていない、と判断できる。「該当行が無ければ 404 を返す」「複数行更新が起きたら警告ログ」などの分岐に使う。

このトピックで最重要の警告が **「WHERE を忘れると全行が対象になる」** こと。`UPDATE users SET age = 0` は全ユーザーの年齢を 0 にする破壊的な文、`DELETE FROM users` はテーブルを空にする。SQL を書くときは「WHERE を書いたか?」を必ず指差し確認するクセを付ける。怖ければ、本番では先に同じ WHERE で `SELECT` して件数を確認してから実行するのが定石。

## 学習目標

- `UPDATE ... SET ... WHERE ...` で既存行を書き換えられる
- `DELETE FROM ... WHERE ...` で行を消せる
- `rowCount()` で影響を受けた行数を取れる
- `WHERE` を忘れると **全行が対象** になる怖さを理解する

## 所要時間

スライド 4 分 + ドリル 2 問 = **15 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | WHERE で 1 件 UPDATE → SELECT で結果確認 |
| 02 | DELETE 後に rowCount を出力 + 残った行を確認 |

## スライド

---
marp: true
theme: dojo
paginate: true
size: 16:9
---

<!--
LLM_CONTEXT:
  Lesson 11 / Chapter 6
  目的: UPDATE / DELETE と rowCount で「何件影響したか」を確認できる
  扱わない: トランザクション (ch08) / SQL インジェクション対策 (ch09)
  読み上げ時間目安: 3 分半〜4 分
-->

# UPDATE と DELETE

Lesson 11 / Chapter 6

---

## UPDATE は「書き換える」

```sql
UPDATE users SET age = 26 WHERE name = '花子';
```

- `SET 列 = 値` で書き換える列を指定
- `WHERE 条件` を **必ず** 付ける
- WHERE を忘れると **全行が書き変わる** (事故)

---

## PHP からも prepare + execute

```php
<?php
$pdo = new PDO('sqlite:' . getenv('DOJO_DB_PATH'));
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmt = $pdo->prepare("UPDATE users SET age = ? WHERE name = ?");
$stmt->execute([26, '花子']);
```

- INSERT と同じ書き方
- `?` は SET の値、WHERE の値、両方に使える

---

## DELETE は「消す」

```sql
DELETE FROM users WHERE id = 2;
```

- `DELETE FROM テーブル` の後に `WHERE 条件`
- これも WHERE を忘れると **全行消える**

```php
<?php
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
$stmt->execute([2]);
```

---

## 影響行数は `rowCount()`

```php
<?php
$stmt = $pdo->prepare("DELETE FROM users WHERE age >= ?");
$stmt->execute([25]);

echo "削除した件数: " . $stmt->rowCount() . "\n";
```

- 直前の UPDATE / DELETE が **何件に影響したか** を返す
- 「該当 0 件だった」のチェックに使える
- SELECT の件数を取るのには **使わない** (SELECT は環境差あり)

---

## 確認は SELECT で

```php
<?php
// DELETE 実行後…
foreach ($pdo->query("SELECT id, name, age FROM users ORDER BY id") as $row) {
    echo "{$row['id']}: {$row['name']} ({$row['age']})\n";
}
```

- UPDATE / DELETE 自体は画面に何も出さない
- 結果を確認するには SELECT で読む

---

## このチャプターでできるようになること

✅ `UPDATE ... SET ... WHERE ...` で書き換えられる
✅ `DELETE FROM ... WHERE ...` で消せる
✅ `rowCount()` で影響行数を取れる
✅ `WHERE` 忘れは全行に影響する事故だと理解した

→ ドリルへ
