> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MySQL の INSERT

> MySQL の INSERT 文が行を追加する仕組み、省略した列にサーバーが入れるもの、そして最初の INSERT が最もよく出会う 2 つのエラー。

> [card] [VillageSQL is a drop-in replacement for MySQL with extensions.](https://villagesql.com/docs/en/8.4/stable/install-server.md)
>
> All examples on this page work on VillageSQL. Install Now →

ここまでのレッスンはすべてデータを読んできました。`INSERT` はデータを書き
ます。ここから先は文がテーブルの中身を変えるので、チュートリアルの残りは
サンプルデータではなく専用のデータベースで作業します。

## 練習用データベース

Sakila はすべての読み取りレッスンが説明する基準なので、そのままにして
おきます。代わりにその横に小さなデータベースを作り、やり直したいときは
いつでもこれをもう一度実行してください。

```sql theme={null}
DROP DATABASE IF EXISTS sakila_practice;
CREATE DATABASE sakila_practice;
USE sakila_practice;

CREATE TABLE member (
  member_id  INT UNSIGNED NOT NULL AUTO_INCREMENT,
  first_name VARCHAR(45) NOT NULL,
  last_name  VARCHAR(45) NOT NULL,
  email      VARCHAR(100) DEFAULT NULL,
  joined     DATE NOT NULL,
  active     TINYINT NOT NULL DEFAULT 1,
  PRIMARY KEY (member_id),
  UNIQUE KEY uq_member_email (email)
);

INSERT INTO member (first_name, last_name, email, joined, active) VALUES
  ('Mary',     'Smith',    'mary.smith@example.com',       '2026-01-04', 1),
  ('Patricia', 'Johnson',  'patricia.johnson@example.com', '2026-02-11', 1),
  ('Linda',    'Williams', 'linda.williams@example.com',   '2026-03-02', 0);

CREATE TABLE rating_count (
  rating VARCHAR(10) NOT NULL,
  films  INT UNSIGNED NOT NULL,
  PRIMARY KEY (rating)
);

CREATE TABLE account (
  account_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  owner      VARCHAR(45) NOT NULL,
  balance    DECIMAL(10,2) NOT NULL,
  PRIMARY KEY (account_id)
);

INSERT INTO account (owner, balance) VALUES
  ('Mary Smith',       500.00),
  ('Patricia Johnson', 250.00);
```

このセクションのすべてのレッスンはその状態から始まります。始める前に
`mysql -u root -p sakila_practice` でクライアントを開き、レッスンの合間に
このブロックをもう一度実行してください。

## INSERT の仕組み

```sql theme={null}
INSERT INTO TABLE_NAME (COLUMN_LIST)
VALUES (VALUE_LIST);
```

`TABLE_NAME` を書き込み先のテーブルに、`COLUMN_LIST` を値を与える列に、
`VALUE_LIST` をそれらの列 1 つにつき 1 つの値に、同じ順番で置き換えます。

サーバーは行を追加し、何行書いたかを報告します。行そのものは表示しない
ので、その後の `SELECT` が結果を見る方法です。

## 例

### 行を追加する

```sql theme={null}
INSERT INTO member (first_name, last_name, email, joined)
VALUES ('Jennifer', 'Davis', 'jennifer.davis@example.com', '2026-03-18');
```

```text theme={null}
Query OK, 1 row affected (0.00 sec)
```

`Query OK` と `1 row affected` が報告のすべてです。何が保存されたかを見るには
テーブルを問い合わせます。

```sql theme={null}
SELECT * FROM member;
```

```text theme={null}
+-----------+------------+-----------+------------------------------+------------+--------+
| member_id | first_name | last_name | email                        | joined     | active |
+-----------+------------+-----------+------------------------------+------------+--------+
|         1 | Mary       | Smith     | mary.smith@example.com       | 2026-01-04 |      1 |
|         2 | Patricia   | Johnson   | patricia.johnson@example.com | 2026-02-11 |      1 |
|         3 | Linda      | Williams  | linda.williams@example.com   | 2026-03-02 |      0 |
|         4 | Jennifer   | Davis     | jennifer.davis@example.com   | 2026-03-18 |      1 |
+-----------+------------+-----------+------------------------------+------------+--------+
4 rows in set (0.00 sec)
```

文は 4 列を指定し、行には 6 列あります。`member_id` は列が
`AUTO_INCREMENT` なので自分で数え上げ、`active` はテーブルが宣言する
`DEFAULT 1` を取りました。

### サーバーが選んだ id を読み戻す

`AUTO_INCREMENT` の値は挿入の間に決まるので、それを知る唯一の方法は尋ねる
ことです。挿入を行ったのと同じセッションで尋ねてください。

```sql theme={null}
INSERT INTO member (first_name, last_name, email, joined)
VALUES ('Barbara', 'Jones', 'barbara.jones@example.com', '2026-03-20');
SELECT LAST_INSERT_ID() AS new_id;
```

```text theme={null}
Query OK, 1 row affected (0.00 sec)

+--------+
| new_id |
+--------+
|      5 |
+--------+
1 row in set (0.00 sec)
```

`LAST_INSERT_ID()` は自分の接続についてだけ答えるので、混雑したサーバーでも
別のセッションの id を渡されることはありません。新しい接続には答えるものが
なく、0 を返します。

## ERROR 1062 は行が既にあるという意味

`UNIQUE` 列は、既に保持している値を持つ 2 つ目の行を拒否します。ここでは
`email` が一意であり、Mary Smith のアドレスは使用済みです。

```sql theme={null}
INSERT INTO member (first_name, last_name, email, joined)
VALUES ('Mary', 'Smith', 'mary.smith@example.com', '2026-05-01');
```

```text theme={null}
ERROR 1062 (23000): Duplicate entry 'mary.smith@example.com' for key 'member.uq_member_email'
```

メッセージは値と、それを拒否したインデックスを名指しします。これで通常は、
本当の重複と、一意にするつもりでそうしなかった列とを区別できます。
[Upsert](https://villagesql.com/docs/ja/tutorial/upsert.md) は、これを想定して代わりに既存の行を更新する文です。

## ERROR 1364 は必須の列が欠けているという意味

`NOT NULL` でデフォルトのない列を省略すると、サーバーには書くものが
ありません。

```sql theme={null}
INSERT INTO member (first_name) VALUES ('Sam');
```

```text theme={null}
ERROR 1364 (HY000): Field 'last_name' doesn't have a default value
```

一度に 1 列ずつ名指しするので、3 列が欠けている文は 3 回かかります。
`DESCRIBE member;` でテーブルを読み、`Null` の下に `NO` と記され、デフォルトの
ないものをすべて与えてください。

NULL を受け入れる列は別の話です。省略すると、行には NULL が入ります。

```sql theme={null}
INSERT INTO member (first_name, last_name, joined)
VALUES ('George', 'Miller', '2026-04-01');
```

```text theme={null}
Query OK, 1 row affected (0.00 sec)
```

## 重複キーでも id は消費される

今 id を問い合わせると、6 が欠けています。

```sql theme={null}
SELECT member_id, first_name, last_name, email, active FROM member;
```

```text theme={null}
+-----------+------------+-----------+------------------------------+--------+
| member_id | first_name | last_name | email                        | active |
+-----------+------------+-----------+------------------------------+--------+
|         1 | Mary       | Smith     | mary.smith@example.com       |      1 |
|         2 | Patricia   | Johnson   | patricia.johnson@example.com |      1 |
|         3 | Linda      | Williams  | linda.williams@example.com   |      0 |
|         4 | Jennifer   | Davis     | jennifer.davis@example.com   |      1 |
|         5 | Barbara    | Jones     | barbara.jones@example.com    |      1 |
|         7 | George     | Miller    | NULL                         |      1 |
+-----------+------------+-----------+------------------------------+--------+
6 rows in set (0.00 sec)
```

重複キーの試行は失敗する前に 6 を取り、InnoDB はその番号を元に戻しません。
`ERROR 1364` の試行は何も取りませんでした。テーブルに届く前に拒否された
からです。このような欠番は正常であり、何も失われていません。この列は
識別子として扱い、行数や、番号が途切れなく続くという約束として扱わないで
ください。

## まとめ

* 行を追加するには `INSERT INTO table (columns) VALUES (values)` と書きます。
* 行そのものではなく、書き込んだ行数が返ります。
* デフォルトや `AUTO_INCREMENT` のある列は省略し、サーバーに埋めさせます。
* `ERROR 1062` は、`UNIQUE` 列が既に持っている値という意味です。
* `ERROR 1364` は、与えなかった必須の列という意味です。
* `AUTO_INCREMENT` 列には欠番が出ます。重複キーの失敗が番号を持ったままになるからです。

## 関連項目

* [複数行の挿入](https://villagesql.com/docs/ja/tutorial/insert-multiple-rows.md) — 1 文で多数の行
* [INSERT SELECT](https://villagesql.com/docs/ja/tutorial/insert-select.md) — 入力する代わりにクエリから得た行
* [Upsert](https://villagesql.com/docs/ja/tutorial/upsert.md) — 挿入するか、邪魔になっている行を更新する
* [UPDATE](https://villagesql.com/docs/ja/tutorial/update.md) — 既にある行を変更する


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.