1回のINSERT(インサートSQL)で複数行のレコードを一括挿入(追加)する

SQLServerやMySQLなどのデータベースで、テーブルにレコードをINSERT文使用して追加するには、通常は以下のように記述します。

テストデータを作成する際などは、大量のレコードが必要になります。
1つのテーブルに複数のレコードを追加する場合、通常は以下のように何行もINSERT文を記述しなければなりません。

上記のSQLでは記述した回数だけINSERT文が繰り返し実行され、テーブルにデータがインサートされます。

これはこれで問題はないのですが、1回のSQLで複数のデータが追加できると、INSERT文の実行が1度だけになりますし、SQLも短くて済みますので非常に便利です。

SQLServerやMySQLなどでは、1回のSQL(INSERT)で複数のデータを挿入する記述ができるようになっています。
そこで今回は、複数行のレコードを1回のINSERTステートメントで挿入する方法を紹介します。

テーブルの準備

本記事では以下のテーブルを使用します。

テーブルの列定義

列名 データ型 PK
KEY_NO int
STRING_VALUE nvarchar(50)
NUMBER_VALUE decimal(18, 0)

テーブルのCREATE文

SQLServerでのテーブルのCREATE文です。

複数レコードの一括INSERT

まずは通常通り1回のINSERT文で1レコードを挿入する場合です。

次にサンプルのSQLを示します。

上記のサンプルでは10レコードを挿入しているので、当然ですがINSERT文は10回実行することになります。

実行結果
KEY_NO STRING_VALUE NUMBER_VALUE
1 VALUE1 100
2 VALUE2 200
3 VALUE3 300
4 VALUE4 400
5 VALUE5 500
6 VALUE6 600
7 VALUE7 700
8 VALUE8 800
9 VALUE9 900
10 VALUE10 1000

次に、1回のINSERT文で複数行のレコードを挿入する場合です。

1回のINSERT文で複数行のレコードを挿入するSQLは簡単です。
1レコードずつINSERTする場合のVALUES句の部分を「,」(カンマ)で区切ってつなげるだけです。

複数レコードの一括INSERTのSQL

以下に複数レコードを一度にINSERTするSQLのサンプルを記載します。

上記のSQLではKEY_VALUEテーブルに10件のレコードを一括でINSERTしています。

実行結果
KEY_NO STRING_VALUE NUMBER_VALUE
1 VALUE1 100
2 VALUE2 200
3 VALUE3 300
4 VALUE4 400
5 VALUE5 500
6 VALUE6 600
7 VALUE7 700
8 VALUE8 800
9 VALUE9 900
10 VALUE10 1000

1レコードずつINSERTする場合は

INSERT INTO KEY_VALUE
  (KEY_NO, STRING_VALUE, NUMBER_VALUE)
VALUES
  (1, ‘VALUE1’, 100);
INSERT INTO KEY_VALUE
  (KEY_NO, STRING_VALUE, NUMBER_VALUE)
VALUES
  (2, ‘VALUE2’, 200);
INSERT INTO KEY_VALUE
  (KEY_NO, STRING_VALUE, NUMBER_VALUE)
VALUES
  (3, ‘VALUE3’, 300);

INSERT INTO KEY_VALUE
  (KEY_NO, STRING_VALUE, NUMBER_VALUE)
VALUES
  (10, ‘VALUE10’, 1000);

となりますが

一括してINSERTする場合は

INSERT INTO KEY_VALUE
  (KEY_NO, STRING_VALUE, NUMBER_VALUE)
VALUES

までを1度だけ記述して、VALUES以降をカンマで区切って記述します。

  (1, ‘VALUE1’, 100),
  (2, ‘VALUE2’, 200),
  (3, ‘VALUE3’, 300),
  …
  (10, ‘VALUE10’, 1000);

VALUES句にエラーがある場合

複数レコードのINSERTでは、VALUES句に1つでもエラーが発生する記述があると1件もレコードの挿入は行われません。

次の例で故意にエラーが発生するINSERT文を実行してみます。
実行するSQLは以下になります。

5行目(VALUES句の2つ目)の「KEY_NOが2」のレコードの「NUMBER_VALUE」に数値ではない「二百」を指定しています。

実行結果

複数行INSERT実行エラー

SELECT文を実行してレコードを取得してみると、すべてのレコードの挿入が取消(ROLLBACK: ロールバック)され、1件のレコードも挿入(COMMIT: コミット)されないことが確認できます。

複数行INSERT実行エラー後のデータを取得

説明は不要かもしれませんが、INSERTを1レコードずつ別に記述して実行した場合は、エラーが発生する前のレコードまではテーブルに挿入されます。

上記の例では「KEY_NOが5」のレコードでエラーが発生するので、「KEY_NOが4」のレコードまでが挿入されます。

実行結果
KEY_NO STRING_VALUE NUMBER_VALUE
1 VALUE1 100
2 VALUE2 200
3 VALUE3 300
4 VALUE4 400

まとめ

本記事では、1回のINSERT文で複数行のレコードを挿入する方法についてご紹介しました。

複数行のレコードを挿入するINSERT文は、INSERT INTO ~ VALUESまでを1度だけ記述し、VALUES句の値の指定部分をカンマで区切って記述するだけでした。
ですので、今まで1レコードずつ挿入するINSERT文を記述していた方でも、簡単に覚えることができます。
また、複数行のレコードを挿入するINSERTは、1レコードずつ挿入するINSERT文を連続して記述する方法に比べても、SQLが読みやすく(見やすく)なります。

複数行を一括挿入するSQLでは、1レコードでもエラーがある場合はレコードは全く挿入されません。
テーブルに挿入したいレコードが複数あり、1件でもエラーがあれば全件挿入しないようにする場合には使えると思います。

複数レコードを1度のINSERT文で実行するSQLは、SQLServerでもMySQLでも実行することができます。

SQLServerは2008以降から複数レコードの一括INSERTができるようになりました。
SQLServer2005以前では実行できないのでご注意ください。
また、1回のINSERTステートメントで挿入できるレコードの上限は1000件になります。
1000件を超えるレコードをINSERTステートメントで実行しようとすると
INSERT ステートメントの行値式の数が、1000 行値の許容最大数を超えています。
というエラーが発生しますので、挿入するレコードが1000件をを超える場合はINSERT文を分けて実行する必要があります。

追記: Oracleの場合

本記事ではSQLServerやMySQLなどで使える、複数行のレコードをテーブルに一括挿入するINSERTスクリプトのご紹介しましたが、OracleではVALUES句の値を指定する部分をカンマで区切る構文で、複数行を1回のINSERT文で追加することができません。
Oracleには、複数行のレコードを一括してINSERTするための「マルチテーブル・インサート」という機能が別途用意されています。
Oracleで1回のSQLで複数行のレコードを挿入するときには、INSERT ALLステートメントを使用します。

INSERT ALLステートメントでは、挿入するレコードごとに、INTO句とテーブル、VALUES句を指定します。
OracleではSQLServerやMySQLのように、VALUES句をまとめて記述することはできませんが、代わりに1回のSQLで複数のテーブルにレコードを挿入することができます。

VALUES句をカンマで連結して記述できないので、SQLの記述量は増えてしまいますが、1回のSQLで複数のテーブルにデータを追加できるのは、非常に便利です。

補足

SQLServerのテーブルに登録されているデータをもとに、INSERT文のSQLスクリプトを生成するプログラムを作成しました。
詳細については、以下の記事を参照してください。

テーブルに登録されているデータからINSERTスクリプトを作成 [SQLServer]
SQL Serverのテーブルに登録されているデータをもとに、INSERTスクリプトを作成するプログラムを作成します。 C#のプログラ...
おすすめの書籍