電子書籍の厳選無料作品が豊富!

データ型の違う日付フィールドを比較した場合同じ日付でもマッチングしないのでしょうか?

SQL 2008
  smalldatetime → 1990/1/1 起点
  datetime → 1753/1/1 起点
  date → 1/1/1起点
ACCESS 2003
  date → 100/1/1 起点

それぞれ日付を整数に変換して保持していると考えています。
ACCESSのdate型の項目に日付を代入してSQLを検索すると同じ日付なのに
  SQLのフィールドの型がdatetime型だとマッチするのですが、
  date型だとマッチしないんです、どうしてでしょうか?

A 回答 (2件)

プロバイダは外のデータとの受渡のインターフェースを提供するものです。


mdbにせよ、adpにせよ、直接SQL Serverのデータにアクセスできるわけではありません。
複数提供されているプロバイダのいずれかを使ってSQL Serverにアクセスして、データのやり取りをしているわけです。

SQL Serverの場合、一般的に使われているのが、
・Microsoft OLE DB Provider for ODBC(MSDASQL)
・Microsoft OLE DB Provider for SQL Server(SQLOLEDB) ~最も一般的
・Microsoft SQL Server Native Client(SQLNCLI)     ~SQL Server 2005対応
・Microsoft SQL Server Native Client 10.0(SQLNCLI10) ~SQL Server 2008対応

ポイントは以下の2点だと思います。
・DATE型はSQL Server 2008で登場したデータ型であり、それ以前には存在しなかったこと
 (したがって、それ以前に提供されているプロバイダはDATE型に対応していない
  =呼び出し元のアプリケーションで問題なく使えるような形で返すことを保証していない)
・MicrosoftのAccess開発チームは、SQL Server 2008に対応できる十分なインターフェースの提供をadpに関して行っていない
 (これはOffice2007でも同じ。内部的にはSQLOLEDB固定で使っていると思います)

したがって、adpでDATE型を使うこと自体をやめた方がいいと私は思っています。

なお、smalldatetimeかdatetimeかについては、ストレージに余裕がなければsmalldatetime、それ以外ならdatetimeでいいと思います。
理由は以下の2点です。
・datetime型の方が優先順位が高いから
 (datetime型とsmalldatetime型の間で演算をすると、smalldatetime型はdatetime型に暗黙変換されます)
・すべてのテーブルで共通して同じ型を使うようにしておいた方が開発上コントロールしやすいから

ご参考までに。
    • good
    • 0
この回答へのお礼

ありがとうございます。

smallもやめて、全て Datetime型 に統一する事にします。

お礼日時:2009/08/13 11:51

CREATE TABLE dttbl (DT1 datetime,DT2 smalldatetime,DT3 date)


GO
INSERT INTO dttbl VALUES ('2009/10/31','2009/10/31','2009/10/31')
GO

--VB/VBAソース
Sub test()
 Dim adCon As New ADODB.Connection
 Dim adRS As New ADODB.Recordset
' adCon.Open "Provider=SQLOLEDB;Data Source=(インスタンス);Initial Catalog=(データベース);User ID=(ユーザID);Password=(パスワード)"
' adCon.Open "Provider=SQLNCLI;Data Source=(インスタンス);Initial Catalog=(データベース);User ID=(ユーザID);Password=(パスワード)"
' adCon.Open "Provider=SQLNCLI10;Data Source=(インスタンス);Initial Catalog=(データベース);User ID=(ユーザID);Password=(パスワード)"

 adRS.Open "SELECT * FROM dttbl", adCon

 Do Until adRS.EOF
  MsgBox adRS.Fields("DT1").Type
  MsgBox adRS.Fields("DT2").Type
  MsgBox adRS.Fields("DT3").Type
  adRS.MoveNext
 Loop
 adRS.Close
 adCon.Close
 Set adRS = Nothing
 Set adCon = Nothing
End Sub

・SQLOLEDB/SQLNCLIの場合
 DT1のType:adDBTimeStamp(135)
 DT2のType:adDBTimeStamp(135)
 DT3のType:adVarWChar(202)
・SQLNCLI10の場合
 DT1のType:adDBTimeStamp(135)
 DT2のType:adDBTimeStamp(135)
 DT3のType:adDBDate(133)

これが「プロバイダが新しい型をサポートしていない」ということの意味です。型が判断できないので文字型として返しています。
文字型と判断されている間は、キャストされない限りシリアル値云々というのは関係がないということでしょう。
    • good
    • 0
この回答へのお礼

ありがとうございます。

昨日試していて「文字列として比較しているのではないか」と
云う所までたどりつけました。

Date型のみSQL側で「/」が「-」に変わって格納されてしまい文字列と
比較してマッチしないようです。
比較時にFormat関数で「yyyy-mm-mm」の形で指定するときちんと
マッチします。

ただ、Findでは上記の状況ですが、Dlookup等の定義域集計関数では
Format関数を使わなくても正常にマッチするようです。
これはプロバイダの関係なんでしょうか?
(プロバイダと云うものを理解できていません、それでも動いているので
なかなか勉強するに至って降りません)

いまいちスッキリしておりません、単純な日付をdatetimeにするか
smalldatetimeにするかで悩みぶり返してしまいました(^^;

お礼日時:2009/08/12 13:03

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!