« データ型のマップ | トップページ | 文字列型の憂鬱 »

2007年10月20日 (土)

日付・時刻型の憂鬱

DB2 CLIつまりODBCでは、日付・時刻に関連するデータベース側のデータ型(ODBCではSQLデータ型と呼ぶ)として、

  • SQL_TYPE_DATE
  • SQL_TYPE_TIME
  • SQL_TYPE_TIMESTAMP
  • SQL_INTERVALで始まる間隔型

が用意されている。

SQL_TYPE_DATEは年、月、日を要素として持つ日付を表すSQLデータ型で、データをアプリケーション側のデータ型(ODBCでは、Cデータ型と呼ぶ)にマップする時に、SQL_C_TYPE_DATEという、Cデータ型としてマップすることができる。SQL_C_TYPE_DATEというCデータ型は、以下のように定義されている。

Odbcdate

上記の構造体にマップすることができる。また、文字列(char *)を表すCデータ型であるSQL_C_CHARにもマップすることもできる。上記のSQL_C_TYPE_DATEにマップする場合、32ビット環境では、2バイト*3フィールド=6バイトのメモリ領域があればいいが、文字列としてSQL_C_CHARにマップする場合、切り捨てが発生しないよう日付を文字列として表現できる十分なメモリを確保する必要がある(日付の区切り文字等を考慮しないといけない)。

SQL_TYPE_TIMEは、時、分、秒を要素として持つ時刻を表すSQLデータ型でSQL_TYPE_DATE同様、Cデータ型として、SQL_C_TYPE_TIMEというデータ型が用意されている。

Odbctime_2

ちなみに、秒は、小数部を持つことができる。

以下同様、SQL_TYPE_TIMESAMPSQL_C_TYPE_TIMESTAMPというCデータ型が用意されている。

Odbctimestamp

で、前回書いたように、DB2のデータ型であるTIMEはSQL_TYPE_TIME、DATEはSQL_TYPE_DATE、TIMESTAMPはSQL_TYPE_TIMESTAMPとして報告されるのである。

悩ましいのはここからで、自分が使ってるデータベースのフレームワークでは、さらに、フレームワークのデータ型にマップさせなければいけないのだが、例えば、フレームワークに用意されている日付型の範囲は0001/01/01~9999/12/31までで、他方、上記のDATE_STRUCT構造体のyearフィールドの型を見ると、SQLSMALLINTで紀元前も許可するではないか・・と、重箱の隅をつつくような事で悩んでいるのである(時刻型の秒の小数点以下の桁数も同様)。幸い、DB2のDATE型は0001年から9999年までであるが・・・(OracleのDATE型は紀元前も許可する)。で、日付・時刻の精度について色々調べたら、こんなブログを発見。では、日付型をフレームワークの文字列型にマップしてはどうか?と考えると、大半の他のアプリケーションがそうであるように、Windowsのロケールの設定から日付や時刻の区切り文字を取得して、文字列を組み立てたくなる(フレームワークの日付・時刻型はそうなっている)。更に本格的にやるとなると、表示後、Windowsのロケールの設定が変更されたら、それを感知し文字列を再組み立てしたくもなる(フレームワークはそうしてる)。

とまぁ、なんて賢いフレームワークなんだ!!と。

ちなみに、DB2には、2つの日付・時刻の差を表す間隔型はないが、ODBCではSQL_INTERVALという接頭辞で始まるSQLデータ型が用意されている。対応するCデータ型もSQL_C_INTERVALという接頭辞が付いており、構造体が用意されている。あいにく、自分の使っているフレームワークではそのような型は用意されていないので、文字列として扱う必要がある。

と色々、汎用的なアプリを作ろうとなると、データベースとアプリケーション側でのデータ型の表現能力の違いで色々悩ましいのである。

« データ型のマップ | トップページ | 文字列型の憂鬱 »

DB2」カテゴリの記事

Oracle」カテゴリの記事

データベース」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1497665/39651818

この記事へのトラックバック一覧です: 日付・時刻型の憂鬱:

« データ型のマップ | トップページ | 文字列型の憂鬱 »

自作ソフトウェア

無料ブログはココログ

メモ