web-dev-qa-db-ja.com

SQL Serverに保存すると、DateTimeのミリ秒が変化する

私はこのように生成した日時を持っています:

DateTime myDateTime = DateTime.Now;

次に、Entity Frameworkを使用して、データベース(DateTime型付き列)に保存します。次に、OData(WCF Data Services)を使用してそれを取得します。

TimeOfDayの値は次のようになります。9:30:03.0196095

TimeOfDayの値は次のようになります。9:30:03.02000

これの正味の効果により、ミリ秒は保存される前は19、再ロードされた後は20と表示されます。

したがって、コードの後半で比較を行うと、等しいはずの場所で失敗します。

SQL Serverの精度は.NETほど高くありませんか?それとも、これを台無しにしているのはEntity FrameworkまたはODataですか?

ミリ秒は切り捨てます(実際には必要ありません)。しかし、なぜこれが起こっているのか知りたいのですが。

32
Vaccano

これは、実際に使用しているSQLサーバーのバージョンによって異なります。

日時フィールドの精度は、小数点以下第3位までです。例:2011-06-06 23:59:59.997および3.33ミリ秒以内でのみ正確です。

あなたの場合、09:30:03.0196095はストレージで09:30:03.020に切り上げられます。

SQL 2008以降、他のデータ型が追加され、小数点以下7桁までで100ナノ秒以内の精度を持つdatetime2などの詳細が提供されました。

詳細については、以下を参照してください。

http://karaszi.com/the-ultimate-guide-to-the-datetime-datatypes

あなたの最善の策は、ミリ秒が重要ではない場合、SQLサーバーに格納する前に2番目の丸めを提供することです。

44
NotMe

これは、SQL datetimeタイプの精度が原因です。 msdnによると:

日時値は、.000、.003、または.007秒の増分に丸められます

このmsdnページRounding of datetime Fractional Second Precisionセクションを見て、丸めがどのように行われるかを理解します。

他の人が示すように、あなたは datetime2 精度を上げるには、datetimeの代わりに:

  • datetime時間範囲は00:00:00 through 23:59:59.997
  • datetime2時間範囲は00:00:00 through 23:59:59.9999999
20
Otiel

SQLでDateTime2を使用できない場合(例:別のシステムで生成されたテーブルを使用しているため、この単一の問題を変更するにはコストがかかる)、丸めを行う簡単なコード変更があります。あなたのために。

参照 System.Dataをインポートし、System.Data.SqlTypes名前空間。次に、SqlDateTime構造体を使用して変換を行うことができます。

DateTime someDate = new SqlDateTime(DateTime.Now).Value;

これにより、値がSQLティックに変換され、精度の低下を含めて.NETティックに戻ります。 :)

警告の言葉、これは元のKind構造のDateTimeを失います(つまりUtcLocal)。この変換も単純な丸めではなく、ティックの計算、MaxTimeの変更などを含む完全な変換があります。したがって、DateTimeの特定のインジケーターに依存している場合は、これを使用しないでください。失われる可能性があります。

4
Andacious

SQL ServerのDateTimeの精度はミリ秒(.fff)。したがって、0.0196は0.020に丸められます。 datetime2 を使用できる場合は、より高い精度が得られます。

3
Mark Wilkins