おひとり

できる限りひとりで楽しむための情報やプログラミング情報など。

【MySQL PostgreSQL】全てのカラムがデフォルト値を持つテーブルに、全てデフォルト値のレコードをINSERTする方法

全てデフォルト値のレコードをINSERTする方法

DDLにて、カラムにはデフォルト値を設定することができます。
そして、INSERTする際に値を指定しない場合は、デフォルト値で初期化されるというのが標準的なRDBMSの動作となります。

そして、そのように全てのカラムにデフォルト値が設定されているテーブルがあり、そのテーブルに全てのカラムの値がデフォルト値であるレコードをINSERTする方法を意外に知らなかったので紹介します。
(少しややこしいですね。笑)
MySQL、PostgreSQLで書き方が異なるため、それぞれ紹介します。

MySQLの場合

サンプルテーブルのスキーマ

テストに使うテーブルを以下のように定義しました。

CREATE TABLE users(
    id INTEGER AUTO_INCREMENT PRIMARY KEY,
    created_at DATETIME DEFAULT NOW()
);

idAUTO_INCREMENTを指定しているため、INSERTのたびにMySQLが設定してくれています。すなわち、デフォルト値を持つといえます。
created_atはINSERTされた際の時刻をデフォルト値として明示しています。

クエリ

このテーブルにINSERTするには、以下のクエリを発行します。

INSERT INTO users VALUES();

この次に紹介するPostgreSQLに比べると直感的なクエリとなります。

実行例

実際に上記クエリを発行すると、以下のようになります。

mysql> INSERT INTO users VALUES();
Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM users;
+----+---------------------+
| id | created_at          |
+----+---------------------+
|  1 | 2019-06-27 04:57:05 |
+----+---------------------+
1 row in set (0.00 sec)

不具合無くINSERTすることができます。
また、SELECTにて、どのような値が設定されたのか確認してます。確かにデフォルト値が設定されています。

PostgreSQLの場合

サンプルテーブルのスキーマ

テーブルのスキーマは以下のようになっています。(MySQLの場合と同様。)

CREATE TABLE users(
    id SERIAL PRIMARY KEY,
    created_at TIMESTAMP DEFAULT NOW()
);

idSERIALなので、INSERTのたびにインクリメントされます。
すなわち、値を指定しなくてもRDBMSが計算してくれた値が設定されます。DEFAULTがついていませんが、実質のデフォルト値であるといえます。
created_atはINSERTされた現在時刻で初期化されます。こちらはDEFAULTによりデフォルト値が明示されています。

クエリ

そして、このテーブルにデフォルト値のみのレコードをINSERTするには、次のようなクエリを発行します。

INSERT INTO users DEFAULT VALUES;

DEFAULT VALUESを指定することにより、全てのカラムの値にデフォルト値を指定できます。
MySQLの場合と異なり、特別な書き方をする必要がある点には注意が必要です。

実行例

以下のように、不具合無くINSERTできます。RETURNINGを使って実際に設定された値を表示しています。

example=# INSERT INTO users DEFAULT VALUES RETURNING id, created_at;
 id |         created_at
----+----------------------------
  2 | 2019-06-27 05:12:37.469232
(1 row)

INSERT 0 1

まとめ

MySQLの場合、次のようなクエリで全てデフォルト値をもつレコードをINSERTできる。

INSERT INTO <テーブル名> VALUES();

PostgreSQLの場合は以下のようなクエリを発行する。

INSERT INTO <テーブル名> DEFAULT VALUES;

参考リンク

dev.mysql.com

www.postgresql.org

f:id:hitoridehitode:20190628072216j:plain