MySQLで日付を扱うにはDATE、TIME、DATATIME、TIMESTAMPなどがありますが、基本は全てDATEの派生です。
今回はこの基本であるDATEについて解説してみたいと思います。
日付を扱うには
先ほども触れましたが、日付を扱うにはDATE型を基本としたいくつかのデータ型を使用します。
DATE型の特徴としては、タイムゾーンに左右されない形でデータベースに保存される点が挙げられます。
これはDATE型がデータベース保存時に文字列として保存されるためです。
DATEのゼロ値
時間型にはそれぞれ「ゼロ」の値の形式が設定されています。
例えばDATEであれば”0000-00-00″、TIMEであれば”00:00:00″、DATETIMEやTIMESTAMPでは”0000-00-00 00:00:00″がこれに当たります。
通常であればこのような日付は存在しませんが、開発するにあたりダミーデータを使う場合などには手っ取り早く使用するケースもあります。
一般的には「ゼロ値=初期設定のデフォルト値」と覚えておけば問題ないと思います。
SQLモード
DATEでゼロ値を扱うことは余りないと思いますが、今回は学習のためにモードについても解説していきます。
このゼロ値の登録が可能かどうかはSQLモードの設定により決定されます。
モードの設定は以下のように行います。
SET GLOBAL sql_mode = 'modes'; SET SESSION sql_mode = 'modes';
通常、インストールしただけの状態ではSQLモードは”NO_ENGINE_SUBSTITUTION”の状態になっています。
このモードの確認は以下のように行います。
SELECT @@GLOBAL.sql_mode; +------------------------+ | @@GLOBAL.sql_mode | +------------------------+ | NO_ENGINE_SUBSTITUTION | +------------------------+ 1 row in set (0.000 sec)
この状態であれば、”0000-00-00 00:00:00″というデータを登録することが出来ます。
NO_ZERO_DATE、NO_ZERO_IN_DATE
先ほど説明したSQLモードがNO_ZERO_DATEとなっている場合、”0000-00-00 00:00:00″というデータを登録することで警告が出ます。
では実際のコードで見てみましょう。
予め作成しておいたテーブルは以下の通りです。
またSQLモードは初期値となっています。
DESC date_table; +-------+------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+------+------+-----+---------+-------+ | date | date | NO | | NULL | | | time | time | NO | | NULL | | +-------+------+------+-----+---------+-------+ 2 rows in set (0.014 sec)
早速このテーブルに”0000-00-00 00:00:00″を追加してみましょう。
INSERT INTO date_table(date, time) VALUES ('0000-00-00', '00:00:00'); Query OK, 1 row affected (0.001 sec) SELECT * FROM date_table; +------------+----------+ | date | time | +------------+----------+ | 0000-00-00 | 00:00:00 | +------------+----------+ 1 row in set (0.000 sec)
特に問題なく登録出来たことが確認できます。
では次にSQLモードを”NO_ZERO_DATE”に変更して再度登録してみましょう。
SET SESSION sql_mode = 'NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION'; Query OK, 0 rows affected (0.000 sec) SELECT @@SESSION.sql_mode; +-----------------------------------------------------+ | @@SESSION.sql_mode | +-----------------------------------------------------+ | NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION | +-----------------------------------------------------+ 1 row in set (0.000 sec) INSERT INTO date_table(date, time) VALUES ('0000-00-00', '00:00:00'); Query OK, 1 row affected, 1 warning (0.002 sec) SELECT * FROM date_table; +------------+----------+ | date | time | +------------+----------+ | 0000-00-00 | 00:00:00 | | 0000-00-00 | 00:00:00 | +------------+----------+ 3 rows in set (0.000 sec)
SQLモードを”NO_ZERO_DATE”に変更すると、INSERTクエリを実行した際に”worning”という文字が出ていることが確認できます。
では最後に厳密SQLモードも試してみましょう。
厳密SQLモードはSQLモードの設定で”STRICT_TRANS_TABLES”を追加することで変更できます。
SET SESSION sql_mode = 'NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,STRICT_TRANS_TABLES'; Query OK, 0 rows affected (0.000 sec) SELECT @@SESSION.sql_mode; +---------------------------------------------------------+ | @@SESSION.sql_mode | +---------------------------------------------------------+ | STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION | +---------------------------------------------------------+ 1 row in set (0.000 sec) INSERT INTO date_table(date, time) VALUES ('0000-00-00', '00:00:00'); ERROR 1292 (22007): Incorrect date value: '0000-00-00' for column `sample_db`.`date_table`.`date` at row 1
厳密SQLモードに変更した場合、INSERTで同じように値を登録しようとしてもエラーが返ってきてしまいました。
このようにモードによって登録可能かどうかが変わってきますので、もしゼロ登録できないようであればまずはSQLモードを確認してみてください。
まとめ
いかがでしたか?
今回はDATEとSQLモードについて解説してみました。
時間型では恐らくDATETIMEを最も使うと思いますが、基本型であるDATEを理解していれば派生の型は大体理解できると思います。
基本をしっかりと身に着けるようにしましょう。
またMySQLを学習する上でSQLモードについての理解も深めておくようにしましょう。