アマテラスに、新しい乗組員「ハルカ」が配属されることになりました。これまで学んだSELECTは、すでにあるデータを取り出すだけの命令でした。テーブルに新しい行を書き加えるには、どんな命令を使えばいいでしょう?
SELECTは「読む」ための命令でした。今回学ぶのは、その逆の「書き込む」ための命令です。少し名前を予想してから読み進めてください。
INSERT INTO ... VALUES の基本形
テーブルに新しい行を追加するには、INSERT文を使います。基本の形はこうです。
INSERT INTO テーブル名 (列名1, 列名2, ...)
VALUES (値1, 値2, ...);
crewテーブルに、ハルカを追加してみましょう。
crew テーブル(追加前):
| id | name | role | age | home | salary |
|---|---|---|---|---|---|
| 1 | ユミ | エンジニア | 24 | 地球 | 320000 |
| 2 | ケンジ | パイロット | 35 | 火星 | 400000 |
| 3 | サクラ | 医師 | 41 | 地球 | 520000 |
| 4 | ハルト | 医師 | 33 | 月 | 450000 |
| 5 | レイ | 研究員 | 29 | 火星 | 380000 |
| 6 | ミドリ | パイロット | 27 | 地球 | 360000 |
| 7 | ソラ | エンジニア | 45 | 月 | 470000 |
| 8 | トウマ | 研究員 | 24 | NULL | 270000 |
| 9 | アカリ | エンジニア | 31 | 火星 | 350000 |
| 10 | リョウ | パイロット | 38 | NULL | 440000 |
INSERT INTO crew (name, role, age, home, salary)
VALUES ('ハルカ', '整備士', 24, '地球', 290000);
crew テーブル(追加後):
| id | name | role | age | home | salary |
|---|---|---|---|---|---|
| 1 | ユミ | エンジニア | 24 | 地球 | 320000 |
| 2 | ケンジ | パイロット | 35 | 火星 | 400000 |
| 3 | サクラ | 医師 | 41 | 地球 | 520000 |
| 4 | ハルト | 医師 | 33 | 月 | 450000 |
| 5 | レイ | 研究員 | 29 | 火星 | 380000 |
| 6 | ミドリ | パイロット | 27 | 地球 | 360000 |
| 7 | ソラ | エンジニア | 45 | 月 | 470000 |
| 8 | トウマ | 研究員 | 24 | NULL | 270000 |
| 9 | アカリ | エンジニア | 31 | 火星 | 350000 |
| 10 | リョウ | パイロット | 38 | NULL | 440000 |
| 11 | ハルカ | 整備士 | 24 | 地球 | 290000 |
新しい行が1件、末尾に加わりました。id を自分で指定していないことに気づいたでしょうか。多くのRDBMSでは、主キーの列を自動的に連番で振ってくれる仕組みがあり、id の指定を省略できます。
列指定の意味
INSERT INTO crew (name, role, age, home, salary) の丸カッコの中は、「これから入れる値が、どの列に対応するか」を示すリストです。そして VALUES (...) 側の値は、列名リストと同じ並び順で対応します。
-- name, role, age, home, salary の順で列を指定したので
-- VALUESの値も同じ順番で並べる
INSERT INTO crew (name, role, age, home, salary)
VALUES ('ハルカ', '整備士', 24, '地球', 290000);
もし列名リストと値の順番がずれると、名前のつもりで書いた値が role 列に入ってしまう、といった事故が起きます。文字列はクォートで囲み、数値は囲まない——WHERE句のときと同じルールも、ここでそのまま生きています。
なお、列名リストをまるごと省略して INSERT INTO crew VALUES (...) と書く方法もありますが、その場合はテーブル定義された全列に、定義順どおりの値を渡す必要があり、列の並びを覚えていないと事故のもとです。列名は省略せず、常に指定するのが安全な書き方です。
複数行INSERT
新しい乗組員が同時に2人配属されることもあります。そんなときは、VALUES のあとにカンマ区切りで複数の値の組を並べれば、1回のINSERT文でまとめて追加できます。
INSERT INTO crew (name, role, age, home, salary)
VALUES
('ハルカ', '整備士', 24, '地球', 290000),
('メイ', '研究員', 30, '月', 305000);
crew テーブル(追加後):
| id | name | role | age | home | salary |
|---|---|---|---|---|---|
| 1 | ユミ | エンジニア | 24 | 地球 | 320000 |
| 2 | ケンジ | パイロット | 35 | 火星 | 400000 |
| 3 | サクラ | 医師 | 41 | 地球 | 520000 |
| 4 | ハルト | 医師 | 33 | 月 | 450000 |
| 5 | レイ | 研究員 | 29 | 火星 | 380000 |
| 6 | ミドリ | パイロット | 27 | 地球 | 360000 |
| 7 | ソラ | エンジニア | 45 | 月 | 470000 |
| 8 | トウマ | 研究員 | 24 | NULL | 270000 |
| 9 | アカリ | エンジニア | 31 | 火星 | 350000 |
| 10 | リョウ | パイロット | 38 | NULL | 440000 |
| 11 | ハルカ | 整備士 | 24 | 地球 | 290000 |
| 12 | メイ | 研究員 | 30 | 月 | 305000 |
INSERT文を2回書くより、まとめて1回で書くほうがシンプルですし、実行の効率も良くなります。追加したい行数が多いときほど、この書き方が役立ちます。
INSERT INTO crew (name, role) VALUES ('ソウタ', 'パイロット', 28); というSQLには、間違いがあります。何が問題でしょう?
答えを見る
列名リストが2つ(name, role)なのに、VALUESの値が3つ('ソウタ', 'パイロット', 28)あり、数が合っていません。
列名リストと値は、個数も順番も一致していなければなりません。もし年齢も入れたいなら、列名リストも (name, role, age) のように3つにそろえる必要があります。
SELECTが「読む」なら、INSERTは「書く」。列名リストと値の対応さえずれなければ、怖い命令じゃないよ。「列名は省略せず、順番をそろえる」——これだけ意識してみてね。
INSERT文はテーブルの中身を書き換える命令なので、検索を中心にしたSQL DIVERでは扱っていません。手元のSQLiteやオンラインのSQL実行環境などで、実際にINSERT文を打ち込んで試してみるのがおすすめです。