全てデフォルト値のレコードをINSERTする方法
DDLにて、カラムにはデフォルト値を設定することができます。
そして、INSERTする際に値を指定しない場合は、デフォルト値で初期化されるというのが標準的なRDBMSの動作となります。
そして、そのように全てのカラムにデフォルト値が設定されているテーブルがあり、そのテーブルに全てのカラムの値がデフォルト値であるレコードをINSERTする方法を意外に知らなかったので紹介します。
(少しややこしいですね。笑)
MySQL、PostgreSQLで書き方が異なるため、それぞれ紹介します。
MySQLの場合
サンプルテーブルのスキーマ
テストに使うテーブルを以下のように定義しました。
CREATE TABLE users( id INTEGER AUTO_INCREMENT PRIMARY KEY, created_at DATETIME DEFAULT NOW() );
id
はAUTO_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() );
id
はSERIAL
なので、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;
参考リンク