« Mac De Oracle Heterogeneous! #20 | トップページ | Mac De Oracle Heterogeneous! #22 »

2006年1月24日 (火) / Author : Hiroshi Sekiguchi.

Mac De Oracle Heterogeneous! #21

つづきです。

今日は、MySQLの日付、時刻型について、Oracleとの違いを見ていく。

最初は、すべて 0 を設定してみる。
なんと正常に登録できてしまう。
しかもOracleやMySQLでも設定できなかった 0月 0日やOracleではエラーになってしまう 0000年が設定できるのである。generic connectivityでは問題になるかもしれないので注意しておく必要がある。

mysql> insert into date_test values(0,0,0,0,0);
Query OK, 1 row affected (0.09 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
+---------------------+------------+---------------------+----------+--------+
7 rows in set (0.00 sec)


nullableなのでNULLを設定しても問題ない。ただし、timestamp型はnullにならず必ずタイムスタンプが設定される。この辺りはOracleでも問題なることはないだろう。

mysql> insert into date_test values(null,null,null,null,null);
Query OK, 1 row affected (0.09 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
+---------------------+------------+---------------------+----------+--------+
8 rows in set (0.00 sec)

mysql>


現在時刻、日付の設定も特に問題になるようなことはなさそうに感じる。ただ warningが出ているが、気にせずcommitすると登録できてしまうので、プログラムミスでwarningを拾わず、rollbackしなかったらおかしな日付が登録される危険性がある。
ちなみに、MySQL4.1.13aでは 1 warningとでているが、MySQL4.0.26-ntでは warining表示すら表示されていなかった。

mysql> insert into date_test values(now(), now(), now(), now(), now());
Query OK, 1 row affected, 1 warning (0.09 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
+---------------------+------------+---------------------+----------+--------+
9 rows in set (0.00 sec)

mysql>

さて、お次は問題。MySQLでは、PostgreSQLでも設定できなかった空文字が warningはでるがコミットはできてしまう。前述したがwarningを拾わずにcommitしてしまうようなプログラムがあれば日付としておかしな値が設定されてしまう危険性がある。

mysql> insert into date_test values('','','','','');
Query OK, 1 row affected, 5 warnings (0.07 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
+---------------------+------------+---------------------+----------+--------+
10 rows in set (0.00 sec)

mysql>

さすがに、13月や35日、26時間、 70分、70秒などは warningとして警告がでるが、やはり commitが行える。内容を見てみると、0000年0月0日 0時0分0秒となる。注意しなければ。。。

mysql> insert into date_test values('2006-13-35 26:70:70',null,null,null,null);
Query OK, 1 row affected, 1 warning (0.06 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:30:56 | NULL | NULL |
+---------------------+------------+---------------------+----------+--------+
11 rows in set (0.00 sec)

mysql> insert into date_test values('99999999',null,null,null,null);
Query OK, 1 row affected, 1 warning (0.04 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:30:56 | NULL | NULL |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:32:31 | NULL | NULL |
+---------------------+------------+---------------------+----------+--------+
12 rows in set (0.00 sec)

mysql>

これもあぶない。0月、0日がワーニングもなく登録できるのである。

mysql> insert into date_test values('2006-00-00 00:00:00',null,null,null,null);
Query OK, 1 row affected (0.06 sec)

mysql> select * from date_test;
+---------------------+------------+---------------------+----------+--------+
| r_datetime | r_date | r_timestamp | r_time | r_year |
+---------------------+------------+---------------------+----------+--------+
| 1990-01-01 00:00:00 | NULL | 2006-01-20 23:04:22 | NULL | NULL |
| 2000-12-01 00:00:00 | NULL | 2006-01-20 23:04:35 | NULL | NULL |
| NULL | 1800-01-01 | 2006-01-20 23:04:51 | NULL | NULL |
| NULL | 1810-12-01 | 2006-01-20 23:05:06 | NULL | NULL |
| NULL | NULL | 2002-12-01 00:00:00 | NULL | NULL |
| NULL | NULL | 2006-01-20 23:05:33 | NULL | NULL |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| NULL | NULL | 2006-01-24 23:12:32 | NULL | NULL |
| 2006-01-24 23:13:19 | 2006-01-24 | 2006-01-24 23:13:19 | 23:13:19 | 2006 |
| 0000-00-00 00:00:00 | 0000-00-00 | 0000-00-00 00:00:00 | 00:00:00 | 0000 |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:30:56 | NULL | NULL |
| 0000-00-00 00:00:00 | NULL | 2006-01-24 23:32:31 | NULL | NULL |
| 2006-00-00 00:00:00 | NULL | 2006-01-24 23:43:53 | NULL | NULL |
+---------------------+------------+---------------------+----------+--------+
13 rows in set (0.00 sec)

mysql>

ざっと確認してみたところ、ポイントは

0000年
0月
0日

それぞれを許容してしまうあたりだろうか。。


次回は、Generic Connectivityを経由してMySQLにアクセスしてみる。Oracle側ではどの型にマッピングされ、どのような癖があるのかを確認する。

| |

トラックバック


この記事へのトラックバック一覧です: Mac De Oracle Heterogeneous! #21:

コメント

コメントを書く