SQLServerやMySQLなどのデータベースで、テーブルにレコードをINSERT文使用して追加するには、通常は以下のように記述します。
1 2 |
-- INSERT文でデータを追加 INSERT INTO テーブル (カラム, カラム) VALUES (データ, データ); |
テストデータを作成する際などは、大量のレコードが必要になります。
1つのテーブルに複数のレコードを追加する場合、通常は以下のように何行もINSERT文を記述しなければなりません。
1 2 3 4 |
INSERT INTO TABLE (COLUMN1, COLUMN2, COLUMN3) VALUES (1, 'STRING1', 100); INSERT INTO TABLE (COLUMN1, COLUMN2, COLUMN3) VALUES (2, 'STRING2', 200); INSERT INTO TABLE (COLUMN1, COLUMN2, COLUMN3) VALUES (3, 'STRING3', 300); -- ...以下1000行以上続く |
上記の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文です。
1 2 3 4 5 6 7 8 9 10 |
-- 複数レコード一括INSERT用テーブル作成 CREATE TABLE KEY_VALUE( KEY_NO int NOT NULL, STRING_VALUE nvarchar(50) NULL, NUMBER_VALUE decimal(18, 0) NULL, CONSTRAINT PK_KEY_VALUE PRIMARY KEY CLUSTERED ( KEY_NO ASC ) ) ON [PRIMARY] |
複数レコードの一括INSERT
まずは通常通り1回のINSERT文で1レコードを挿入する場合です。
次にサンプルのSQLを示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
-- 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 (4, 'VALUE4', 400); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (5, 'VALUE5', 500); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (6, 'VALUE6', 600); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (7, 'VALUE7', 700); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (8, 'VALUE8', 800); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (9, 'VALUE9', 900); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (10, 'VALUE10', 1000); |
上記のサンプルでは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のサンプルを記載します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
-- 複数レコード一括INSERT INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (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); |
上記の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する場合は
(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する場合は
(KEY_NO, STRING_VALUE, NUMBER_VALUE)
VALUES
までを1度だけ記述して、VALUES以降をカンマで区切って記述します。
(2, ‘VALUE2’, 200),
(3, ‘VALUE3’, 300),
…
(10, ‘VALUE10’, 1000);
VALUES句にエラーがある場合
複数レコードのINSERTでは、VALUES句に1つでもエラーが発生する記述があると1件もレコードの挿入は行われません。
次の例で故意にエラーが発生するINSERT文を実行してみます。
実行するSQLは以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (1, 'VALUE1', 100), (2, 'VALUE2', '二百'), (3, 'VALUE3', 300), (4, 'VALUE4', 400), (5, 'VALUE5', 500), (6, 'VALUE6', 600), (7, 'VALUE7', 700), (8, 'VALUE8', 800), (9, 'VALUE9', 900), (10, 'VALUE10', 1000); |
5行目(VALUES句の2つ目)の「KEY_NOが2」のレコードの「NUMBER_VALUE」に数値ではない「二百」を指定しています。
SELECT文を実行してレコードを取得してみると、すべてのレコードの挿入が取消(ROLLBACK: ロールバック)され、1件のレコードも挿入(COMMIT: コミット)されないことが確認できます。
説明は不要かもしれませんが、INSERTを1レコードずつ別に記述して実行した場合は、エラーが発生する前のレコードまではテーブルに挿入されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
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 (4, 'VALUE4', 400); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (5, 'VALUE5', '五百'); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (6, 'VALUE6', 600); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (7, 'VALUE7', 700); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (8, 'VALUE8', 800); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (9, 'VALUE9', 900); INSERT INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (10, 'VALUE10', 1000); |
上記の例では「KEY_NOが5」のレコードでエラーが発生するので、「KEY_NOが4」のレコードまでが挿入されます。
1 |
SELECT * FROM KEY_VALUE |
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ステートメントを使用します。
1 2 3 4 5 6 7 8 9 10 11 12 |
INSERT ALL INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (1, 'VALUE1', 100) INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (2, 'VALUE2', 200) INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (3, 'VALUE3', 300) INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (4, 'VALUE4', 400) INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (5, 'VALUE5', 500) INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (6, 'VALUE6', 600) INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (7, 'VALUE7', 700) INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (8, 'VALUE8', 800) INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (9, 'VALUE9', 900) INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (10, 'VALUE10', 1000) SELECT * FROM DUAL; |
INSERT ALLステートメントでは、挿入するレコードごとに、INTO句とテーブル、VALUES句を指定します。
OracleではSQLServerやMySQLのように、VALUES句をまとめて記述することはできませんが、代わりに1回のSQLで複数のテーブルにレコードを挿入することができます。
1 2 3 4 |
INSERT ALL INTO KEY_VALUE (KEY_NO, STRING_VALUE, NUMBER_VALUE) VALUES (1, 'VALUE1', 100) INTO CODE_NAME (CODE_VALUE, NAME_VALUE) VALUES ('CODE1', 'NAME1') SELECT * FROM DUAL; |
VALUES句をカンマで連結して記述できないので、SQLの記述量は増えてしまいますが、1回のSQLで複数のテーブルにデータを追加できるのは、非常に便利です。
補足
SQLServerのテーブルに登録されているデータをもとに、INSERT文のSQLスクリプトを生成するプログラムを作成しました。
詳細については、以下の記事を参照してください。