連載
» 2005年05月27日 00時00分 公開

日付データ演算の達人技を伝授する 【第3話】SQLクリニック(4)(2/3 ページ)

[山下正,株式会社インサイトテクノロジー]

タイムゾーンの確認

 現在のタイムゾーンの設定は下記のSQLで確認することができます。

SQL> SELECT dbtimezone FROM dual;
DBTIME
------
+00:00
リスト1 データベース・タイムゾーンの確認
SQL> SELECT sessiontimezone FROM dual;
SESSIONTIMEZONE
---------------
GMT
リスト2 セッション・タイムゾーンの確認

 上記の「+00:00」と「GMT」はともにグリニッジ標準時で同じ意味です。設定の仕方で表示方法が変わる例として挙げてみました。タイムゾーンはCREATE DATABASE文で設定する、あるいは後述のALTER DATABASE文で変更する際にタイムゾーン名で設定するか、オフセット値で設定するかで変わります。

 さて、TIME ZONE情報はどのように表示されるかというと、次のような表示になります。

SQL> SELECT systimestamp FROM dual;
SYSTIMESTAMP
-------------------------------
05-05-17 04:26:23.476000 +09:00
リスト3 TIME ZONE情報の表示位置

 右端の「+09:00」がタイムゾーンを表しています。

 話が前後しますが、SYSTIMESTAMP関数で取得される情報はサーバの時刻を表していますので、セッション・タイムゾーンやデータベース・タイムゾーンを変更しても変化はありません。これはSYSDATE関数についても同様です。

タイムゾーンの変更

 タイムゾーンは変更できます。現在のタイムゾーンを確認したところ「ああーっまずい! 設計時点のタイムゾーンと違う。全部作り直しだー」とあきらめる前に、以下のALTER文で変更できないかどうか確認してみてください。

データベース・タイムゾーンの変更

 通常CREATE DATABASEの際に決定するのですが、条件(注3)を満たす場合はデータベース作成後に変更することも可能です。

SQL> ALTER database SET time_zone = 'US/Arizona';

または、

SQL> ALTER database SET time_zone = '-08:00';

セッション・タイムゾーンの変更

SQL> ALTER session SET time_zone = 'US/Arizona';

または、

SQL> ALTER session SET time_zone = '-08:00';

データベース・タイムゾーン変更の条件

注3 データベース内にTIMESTAMP WITH LOCAL TIME ZONE型の列を持つテーブルが存在する場合は、データベース・タイムゾーンの変更はできません。これは、TIMESTAMP

WITH LOCAL TIME ZONE型のデータがデータベース・タイムゾーンに従ってデータを格納しているためです。つまりデータベース・タイムゾーンを変更する場合は、TIMESTAMP

WITH LOCAL TIME ZONE型の列を持つテーブルをすべてDROPするか、TIMESTAMP WITH LOCAL TIME ZONE型の列をすべてDROPしなければなりません。データが0件でもエラーになります……なので、TRUNCATEで手を抜こうとしても駄目ですよ。


また、データベース・タイムゾーンはALTER DATABASE文で変更後にインスタンスを再起動しないと反映されないので注意してください。


 参考までに、異なるセッション・タイムゾーンでデータ型が違うと表示がどのように異なるか見ておきましょう。

SQL> SELECT dbtimezone FROM dual;
DBTIME
------
+09:00
SQL> SELECT sessiontimezone FROM dual;
SESSIONTIMEZONE
---------------
+09:00
SQL> CREATE TABLE hogehoge (
  2   c1 timestamp(6)
  3  ,c2 timestamp(6) with time zone
  4  ,c3 timestamp(6) with local time zone
  5  );
Table created.
SQL> INSERT INTO hogehoge (
  2   c1
  3  ,c2
  4  ,c3
  5  ) values (
  6   to_timestamp('2005/05/14 12:34:56.123456', 'yyyy/mm/dd hh24:mi:ss.ff')
  7  ,to_timestamp('2005/05/14 12:34:56.123456', 'yyyy/mm/dd hh24:mi:ss.ff')
  8  ,to_timestamp('2005/05/14 12:34:56.123456', 'yyyy/mm/dd hh24:mi:ss.ff')
  9  );
1 row created.
SQL> commit;
Commit complete.
SQL> SELECT * FROM hogehoge;
C1                       C2                              C3
------------------------ ------------------------------- ------------------------
05-05-14 12:34:56.123456 05-05-14 12:34:56.123456 +09:00 05-05-14 12:34:56.123456
リスト4 異なるデータ型で日付データを格納

 同じデータを異なるタイムゾーンで確認すると、リスト5のようになります。

SQL> ALTER session SET time_zone = 'US/Arizona';
Session altered.
SQL> SELECT * FROM hogehoge;
C1                       C2                              C3
------------------------ ------------------------------- ------------------------
05-05-14 12:34:56.123456 05-05-14 12:34:56.123456 +09:00 05-05-13 20:34:56.123456
リスト5 同じデータを異なるタイムゾーンで取得

 C1列(TIMESTAMP型)では、変化がありません。つまり、タイムゾーンの変化が考慮されていないことになります。

 C2列(TIMESTAMP WITH TIME ZONE型)も変化がありません。が、そもそもデータとしてタイムゾーンの情報が含まれているため、その評価は可能です。

 C3列(TIMESTAMP WITH LOCAL TIME ZONE型)は時刻が変化しています。データベースの処理としてセッション・タイムゾーンを反映して変換されていることが分かります。(次ページに続く)

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。