> ## 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 で複数行を挿入する

> 1 つの MySQL INSERT 文で多数の行を追加する方法、Records と Duplicates の行が報告する内容、そして 1 つの不正な行が文全体を破棄させる理由。

> [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 →

1 つの `INSERT` には好きなだけ行を載せられます。各行の括弧をカンマで区切り
ます。1 行につき 1 文を書くより入力量が少なく、サーバーへの往復も多数回では
なく 1 回で済みます。

これらの例では、[INSERT](https://villagesql.com/docs/ja/tutorial/insert.md) の `sakila_practice` データベースを
使います。始める前にそこにあるセットアップブロックをもう一度実行し、次に
`mysql -u root -p sakila_practice` でクライアントを開いてください。

## 複数行 INSERT の仕組み

```sql theme={null}
INSERT INTO TABLE_NAME (COLUMN_LIST) VALUES
  (FIRST_ROW_VALUES),
  (SECOND_ROW_VALUES);
```

`TABLE_NAME` をテーブルに、`COLUMN_LIST` を値を与える列に、`FIRST_ROW_VALUES`
と `SECOND_ROW_VALUES` のそれぞれを、それらの列 1 つにつき 1 つの値に置き換え
ます。

列リストは 1 回だけ書き、すべての行に適用されます。各括弧は、その順番で値を
与えます。

## 例

### 1 文で 3 行

```sql theme={null}
INSERT INTO member (first_name, last_name, email, joined) VALUES
  ('Jennifer', 'Davis',  'jennifer.davis@example.com',  '2026-03-18'),
  ('Barbara',  'Jones',  'barbara.jones@example.com',   '2026-03-19'),
  ('Elizabeth','Brown',  'elizabeth.brown@example.com', '2026-03-21');
```

```text theme={null}
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
```

2 行目は、文が 2 行以上を書き込みうるときに常に表示されます。複数行の
`VALUES` リストと、あらゆる
[INSERT SELECT](https://villagesql.com/docs/ja/tutorial/insert-select.md) がこれに該当します。`Records` は
送った行数を、`Duplicates` は既に保存されている行と衝突した行数を、
`Warnings` はサーバーが調整しなければならなかったものを数えます。3 つの数字が
すべて送ったものと一致していれば、何も静かに変更されていないという印です。

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

```text theme={null}
+-----------+------------+-----------+
| member_id | first_name | last_name |
+-----------+------------+-----------+
|         1 | Mary       | Smith     |
|         2 | Patricia   | Johnson   |
|         3 | Linda      | Williams  |
|         4 | Jennifer   | Davis     |
|         5 | Barbara    | Jones     |
|         6 | Elizabeth  | Brown     |
+-----------+------------+-----------+
6 rows in set (0.00 sec)
```

id は行が書かれた順に続いています。

## 1 つの不正な行が文全体を破棄させる

下の文は 3 行を載せています。真ん中の行は Mary Smith のアドレスを再利用して
おり、`email` の `UNIQUE` インデックスがそれを拒否します。

```sql theme={null}
INSERT INTO member (first_name, last_name, email, joined) VALUES
  ('Maria',  'Miller', 'maria.miller@example.com', '2026-04-02'),
  ('Susan',  'Wilson', 'mary.smith@example.com',   '2026-04-03'),
  ('Margaret','Moore', 'margaret.moore@example.com','2026-04-04');
```

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

他の 2 行も保存されませんでした。

```sql theme={null}
SELECT COUNT(*) AS members FROM member;
```

```text theme={null}
+---------+
| members |
+---------+
|       6 |
+---------+
1 row in set (0.00 sec)
```

1 つの文は全か無かなので、1 つの不正な値を含む 10,000 行のバッチは何も
書き込みません。全か無かということは、大きなバッチは送信前にデータを
確認しておく必要があるということでもあります。サーバーは問題のある行を
1 つ名指しして止まるからです。

## INSERT IGNORE はエラーを警告に変える

`INSERT IGNORE` は保存できる行を保存し、残りをスキップします。

```sql theme={null}
INSERT IGNORE INTO member (first_name, last_name, email, joined) VALUES
  ('Maria',  'Miller', 'maria.miller@example.com', '2026-04-02'),
  ('Susan',  'Wilson', 'mary.smith@example.com',   '2026-04-03');
SHOW WARNINGS;
```

```text theme={null}
Query OK, 1 row affected, 1 warning (0.00 sec)
Records: 2  Duplicates: 1  Warnings: 1

+---------+------+---------------------------------------------------------------------------+
| Level   | Code | Message                                                                   |
+---------+------+---------------------------------------------------------------------------+
| Warning | 1062 | Duplicate entry 'mary.smith@example.com' for key 'member.uq_member_email' |
+---------+------+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
```

`Records: 2  Duplicates: 1` は起きたことをそのまま報告しています。2 行を
差し出し、1 行が拒否されました。次に `SHOW WARNINGS` がそれを名指しし、同じ
`ERROR 1062` のテキストが失敗ではなく警告として届きます。

```sql theme={null}
SELECT COUNT(*) AS members FROM member;
```

```text theme={null}
+---------+
| members |
+---------+
|       7 |
+---------+
1 row in set (0.00 sec)
```

`IGNORE` は、重複が本当に「既に持っている」という意味のときに使ってください。
それ以外では大雑把すぎる手段です。列に対して長すぎる値や、必須の列に値のない行を
含め、他のエラーも格下げしてしまうからです。`INSERT IGNORE` のたびに
`SHOW WARNINGS` を実行してください。そうしなければ、何が捨てられたか分かり
ません。既に保存されている行を更新するのが正しい答えである場合は、代わりに
[upsert](https://villagesql.com/docs/ja/tutorial/upsert.md) を使ってください。

## まとめ

* 各行の括弧をカンマで区切り、列リストは 1 回だけ書きます。
* `Records`、`Duplicates`、`Warnings` を読んで、何も調整されなかったことを確認します。
* 1 行が拒否されると文全体が中止され、何も書き込まれません。
* 正常な行を保存するには `INSERT IGNORE` を使い、その後で `SHOW WARNINGS` を読みます。
* 単一行の文を多数書くより、複数行の文を 1 つ書くほうを選びます。

## 関連項目

* [INSERT](https://villagesql.com/docs/ja/tutorial/insert.md) — 単一行の形式と、それが起こすエラー
* [INSERT SELECT](https://villagesql.com/docs/ja/tutorial/insert-select.md) — クエリから取り出した行
* [Upsert](https://villagesql.com/docs/ja/tutorial/upsert.md) — スキップする代わりに既存の行を更新する
* [MySQL の一括挿入](https://villagesql.com/docs/ja/guides/bulk-inserts.md) — バッチサイズ、LOAD DATA、そして重要な設定


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