S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

datetime2 データ型の変換は、datetime データ型に範囲外の値になりました。

.NET Framework 3.5
SQL Server 2008
対象となるテーブルのあるカラムの型がDATETIME型の場合に、UpdateあるいはDeleteを行うと例外OutOfRangeExceptionが発生する。


ADOレベルの話か、Entity Frameworkレベル(の話かまで特定できていないが、UpdateあるいはDeleteするレコードを取得したタイミングで、ORマッピングにより生成されたDATETIME型のカラムの.NET上の型がDATETIME2型用の型なのか?という感じ。
UpdateあるいはDeleteするレコードのDATETIME型のカラムの値に、DateTime.Nowを与えると例外は発生しない。
DateTime.NowはDATETIME型にマッピングできる型らしい。


.NET Framework Data Provider for SQL Server (SqlClient) (Entity Framework 用)
ProviderManifestToken スキーマ属性を"2005"にすればいい的な記事も見かけたが、状況は変わらなかったらしい。
Entity Framework: The version of SQL Server in use does not support datatype ‘datetime2′

ただ、この方法でうまくいったとしても、現在の作業の解決策としてはふさわしくないかな。


DATETIME2型は日付の範囲の拡大、タイムゾーンの導入などされているようなので、OutOfRangeExceptionというのも頷ける。
SQL Server 2008 における日付と時刻のデータ (ADO.NET)
ただUpdateはともかく、なんでDeleteで例外が発生するのかは謎(DATETIME型なのは主キーじゃなく属性)。


とりあえず人に検証してもらってる最中なので、現時点ではここまで。
対策としては、SQL Server 2005からの移行対象のデータ(既存テーブルのカラム)の話なので、移行時にDATETIME2型にする方向で検討中。



にしても、言語・DBMS問わず日付・時刻系の話はいろいろあるね。
System.ArgumentOutOfRangeExceptionについて − Insider.NET − @IT

追記(2010/12/24)

ProviderManifestToken スキーマ属性を"2005"にして、リビルドしたらOKになったらしい。
きっとマップする型の定義みたいなもんが、あるんじゃろうとは思よったけど。
で、既存の他システムがテーブルを参照しているため、DATETIME型でスキーマ属性を"2005"にすることにした。