回答:
以下のためのMSDNドキュメント日時が使用することをお勧めしますDATETIME2を。ここに彼らの推薦があります:
使用し
time
、date
、datetime2
とdatetimeoffset
新しい仕事のためのデータ型を。これらの型は、SQL標準に準拠しています。彼らはよりポータブルです。time
、datetime2
そしてdatetimeoffset
より多くの秒の精度を提供します。datetimeoffset
グローバルに展開されたアプリケーションにタイムゾーンのサポートを提供します。
datetime2は、日付範囲が大きく、デフォルトの小数精度が大きく、オプションでユーザー指定の精度があります。また、ユーザー指定の精度によっては、使用するストレージが少なくなる場合があります。
DateTime2
以外に、タイプ(またはその他のSQL Server)の特定のビットレベル表現に実際に依存するアプリはありますかその件について入力してください)?なぜ私が質問しているのかについては、以下の私の7/10/17回答の短所を参照してください
DATETIME2
DATETIME
タイプは「0001/01/01 」から「9999/12/31 」までの日付範囲を持ちますが、タイプは年1753-9999のみをサポートします。
また、必要に応じて、 DATETIME2
時間を正確にすることができます。DATETIMEは3 1/3ミリ秒に制限されていますが、DATETIME2
正確には100nsまで可能です。
どちらのタイプも System.DateTime
.NETでれます-違いはありません。
選択肢があれば、DATETIME2
なるべく使用することをお勧めします。を使用して何の利点も見ていませんDATETIME
(下位互換性を除く)-問題が少なくなります(日付が範囲外であり、そのような手間がかかります)。
さらに、日付のみが必要な場合(時刻部分なし)はDATEを使用します-日付も同じで、DATETIME2
スペースも節約できます。:-)同じことが時間のみに適用されます-使用してくださいTIME
。それがこれらのタイプの目的です!
Nullable<DateTime>
ためですか?
datetime2は、(古いアプリの互換性)を除いて、ほとんどの面で勝利します
次の点に注意してください
画像ソース: MCTS Self-Paced Training Kit(Exam 70-432):Microsoft®SQLServer®2008-Implementation and Maintenance Chapter 3:Tables- > Lesson 1:Creating Tables- > 66ページ
datetime2
素晴らしいです(受賞)
datetime2
使用するストレージスペースが少ないdatetime
のに、より広い範囲と高い精度を実現するにはどうすればよいですか
@marc_sと@Adam_Powardに同意します-今後はDateTime2が推奨される方法です。日付の範囲が広く、精度が高く、使用するストレージは(精度に応じて)以下です。
しかし、議論が失敗したことの1つ...
@Marc_sは次のように述べていますBoth types map to System.DateTime in .NET - no difference there
。これは正しいですが、逆は当てはまりません。日付範囲検索を実行する場合は重要です(たとえば、「2010年5月5日に変更されたすべてのレコードを検索してください」)。
.NETのバージョンの Datetime
範囲と精度はと似ていますDateTime2
。.net Datetime
を古いSQLにマッピングするとDateTime
、暗黙的な丸めが発生します。古いSQLのDateTime
精度は3ミリ秒です。これは11:59:59.997
、1日の終わりに到達できる限り近いことを意味します。それ以上の場合は翌日に切り上げられます。
これを試して :
declare @d1 datetime = '5/5/2010 23:59:59.999'
declare @d2 datetime2 = '5/5/2010 23:59:59.999'
declare @d3 datetime = '5/5/2010 23:59:59.997'
select @d1 as 'IAmMay6BecauseOfRounding', @d2 'May5', @d3 'StillMay5Because2msEarlier'
この暗黙的な丸めを回避することは、DateTime2に移行する大きな理由です。日付の暗黙的な丸めは明らかに混乱を引き起こします:
20100505
に切り替えたのはなぜ5/5/2010
ですか?前者の形式は、SQL Serverのどのリージョンでも機能します。後者は壊れます:SET LANGUAGE French; SELECT Convert(datetime, '1/7/2015')
おっと:2015-07-01 00:00:00.000
ほとんどすべての回答とコメントは長所に重く、短所に軽いです。これまでのすべての長所と短所と、私が一度だけ言及したか、まったく言及していない重要な短所(以下の#2)の要約です。
1.1。よりISO準拠(ISO 8601)(これが実際にどのように機能するかはわかりませんが)。
1.2。より広い範囲(1/1/0001から12/31/9999対1/1 / 1753-12 / 31/9999)(ただし、1753年より前のすべての追加の範囲は、ex。歴史、天文、地質学などのアプリで)。
1.3。.NETのDateTime
Typeの範囲に完全に一致します(ただし、値がターゲットのTypeの範囲と精度の範囲内にある場合は、特別なコーディングなしで前後に変換されます。それ以外の場合、Con#2.1を除き、エラー/丸めが発生します)。
1.4。より高い精度(100ナノ秒、つまり0.000,000,1秒vs. 3.33ミリ秒、つまり0.003,33秒)(ただし、追加の精度は、エンジニアリング/科学アプリなどで使用される場合を除いて、おそらく使用されません)。
1.5。用に設定する場合と同様の(イマンAbidiが主張したように)3.33ミリ秒のように(「同じ」ではない1ミリ秒のように)としての精度をDateTime
、より少ないスペース(7 8対バイト)を使用しますが、その後、もちろん、あなたが失うことだろうおそらく2つのうちの1つである精度の利点(もう一方は範囲です)は、不必要な利点である可能性がありますが、最も宣伝されています)。
2.1。パラメータを.NETに渡すときは、SQL Server の範囲や精度以外の値を渡す可能性があるかどうかをSqlCommand
指定する必要があります。System.Data.SqlDbType.DateTime2
DateTime
System.Data.SqlDbType.DateTime
2.2。暗黙的に/簡単に浮動小数点数値(最小日時からの日数)に変換して、数値と演算子を使用するSQL Server式で次の操作を行うことはできません。
2.2.1。日数または一部の日数を加算または減算します。注:DateAdd
日時のすべてではないにしても複数を考慮する必要がある場合、関数を回避策として使用することは簡単ではありません。
2.2.2。「年齢」の計算のために、2つの日時の差を取ります。注:DateDiff
代わりにSQL Serverの関数を単純に使用することはできませんage
。2つの日時が偶然に指定された単位のカレンダー/時計の日時境界を越えた場合でも、ほんの一部であっても、ほとんどの人が期待するように計算されないためです。その単位の差は、その単位の1と0の差として返されます。たとえば、1ミリ秒しか離れていない2つの日時のDateDiff
inはDay
、それらの日時が1である場合、0と1(0)を返します。異なる暦日(つまり、「1999-12-31 23:59:59.9999999」と「2000-01-01 00:00:00.0000000」)。同じ1ミリ秒の日付と時刻を移動して、暦日を越えないようにするとDay
、0(日)の「DateDiff」が返されます。
2.2.3。Avg
最初に「Float」に変換してから再びに戻すだけで、(集約クエリの)日時を取得しDateTime
ます。
注:DateTime2
数値に変換するには、次の数式のようにする必要があります。これは、値が1970年以上であることを前提としています(つまり、余分な範囲とさらに217年がすべて失われることを意味します。注:数値のオーバーフローの問題に遭遇する可能性があるため、追加の範囲を可能にするために式を単純に調整することはできません。
25567 + (DATEDIFF(SECOND, {d '1970-01-01'}, @Time) + DATEPART(nanosecond, @Time) / 1.0E + 9) / 86400.0
–ソース:「https://siderite.dev/blog/how-to-translate-t-sql-datetime2-to.html」
もちろん、あなたも可能性Cast
へのDateTime
最初の(そして必要なバックは再びへの場合DateTime2
)がありますが、精度と範囲の(すべての前年の1753年)の利益を失うと思いDateTime2
対DateTime
prolly 2最大とも同時にprollyです加算/減算/「年齢」(対DateDiff
)/ Avg
計算の利点のために浮動小数点数値(日数)への暗黙的/簡単な変換を失うときになぜそれを使用するのか疑問を投げかける2つの最も可能性の低いもの私の経験では。
ところで、Avg
日時のは重要な使用例です(または少なくともそうする必要があります)。a)日時(共通の基本日時)が期間を表すために使用されている場合に平均期間を取得するために使用する以外に(一般的な方法)、b)平均日付に関するダッシュボードタイプの統計を取得することも役立ちます-時間は、行の範囲/グループの日時列にあります。c)列内の値を監視/トラブルシューティングするための標準(または少なくとも標準である必要がある)アドホッククエリは、有効でなくなる可能性があり、もはや/または非推奨にする必要がある可能性があります。 (利用可能な場合)Min
、Avg
およびMax
その値に関連付けられた日時スタンプ。
DateTime
)はるかに必要とされる利点であり、すべてSQL Serverのクエリとステートメントへの影響に関連しています。
DateTime2
すでに述べた(オーバーフローの可能性が高いため))。再 「ほとんどの日付タイプでは機能しません」:1つで機能すれば十分であり、ほとんどのアプリのほとんどの日付は、存続期間全体にわたって別の日付タイプに変換する必要はおそらくありません(おそらく、前述のように、DateTime2
とDateTime
(例えば「日付の計算」を行う; P)、それはプログラムだけでなく、広告がアドホック研究は、非算術優しいdate型を使用するように照会していないだけでコーディングすべての余分な価値はないことを考える。。
問題のフィールドにNow()を書き込もうとしているAccess開発者がいる場合、DateTime2は大混乱を引き起こします。Access-> SQL 2008 R2に移行しただけで、すべての日時フィールドがDateTime2として配置されました。爆撃された値としてNow()を使用してレコードを追加します。それは1/1/2012 2:53:04 PMでは問題ありませんでしたが、1/10/2012 2:53:04 PMでは問題ありませんでした。
かつてキャラクターが違いを生んだ。それが誰かを助けることを願っています。
smalldatetime、datetime、datetime2(0)、datetime2(7)のストレージサイズ(バイト)と精度の違いを示す例を次に示します。
DECLARE @temp TABLE (
sdt smalldatetime,
dt datetime,
dt20 datetime2(0),
dt27 datetime2(7)
)
INSERT @temp
SELECT getdate(),getdate(),getdate(),getdate()
SELECT sdt,DATALENGTH(sdt) as sdt_bytes,
dt,DATALENGTH(dt) as dt_bytes,
dt20,DATALENGTH(dt20) as dt20_bytes,
dt27, DATALENGTH(dt27) as dt27_bytes FROM @temp
戻る
sdt sdt_bytes dt dt_bytes dt20 dt20_bytes dt27 dt27_bytes
2015-09-11 11:26:00 4 2015-09-11 11:25:42.417 8 2015-09-11 11:25:42 6 2015-09-11 11:25:42.4170000 8
したがって、ミリ秒単位ではなく秒単位で情報を格納したい場合、datetimeまたはdatetime2(7)の代わりにdatetime2(0)を使用すると、それぞれ2バイトを節約できます。
古い質問...しかし、まだ誰も述べていない何かをここに追加したい...(注:これは私自身の観察なので、参照を要求しないでください)
フィルター基準で使用すると、Datetime2の方が高速です。
TLDR:
SQL 2016では、正確な時刻を秒単位で格納する必要があったため、10万行のテーブルと日時列ENTRY_TIMEがありました。多くの結合とサブクエリを含む複雑なクエリを実行しているときに、where句を次のように使用した場合:
WHERE ENTRY_TIME >= '2017-01-01 00:00:00' AND ENTRY_TIME < '2018-01-01 00:00:00'
何百もの行がある場合、クエリは最初は問題ありませんでしたが、行数が増えると、クエリは次のエラーを出し始めました。
Execution Timeout Expired. The timeout period elapsed prior
to completion of the operation or the server is not responding.
where句を削除したところ、予想外に、クエリは1秒で実行されましたが、すべての日付のすべての行がフェッチされました。where句を使用して内部クエリを実行すると85秒かかり、where句を使用しない場合は0.01秒かかりました。
日時フィルタリングのパフォーマンスとして、この問題のためにここで多くのスレッドに出くわしました
クエリを少し最適化しました。しかし、私が得た実際の速度は、datetime列をdatetime2に変更することでした。
これで、以前にタイムアウトになった同じクエリの実行時間が1秒未満になりました。
乾杯
日付文字列の解釈にdatetime
およびdatetime2
米国以外の使用しているとき、あまりにも異なることができDATEFORMAT
、設定を。例えば
set dateformat dmy
declare @d datetime, @d2 datetime2
select @d = '2013-06-05', @d2 = '2013-06-05'
select @d, @d2
これを返す2013-05-06
ために(つまり、5月6日)datetime
、及び2013-06-05
(つまり、6月5日)のためにdatetime2
。しかし、とのdateformat
セットにmdy
両方、@d
および@d2
リターン2013-06-05
。
このdatetime
動作は、MSDNのドキュメントに次のようSET DATEFORMAT
に記載されているのとは異なります。ISO8601などの一部の文字列形式は、DATEFORMAT設定とは無関係に解釈されます。。明らかに本当ではない!
これに悩まされるまでyyyy-mm-dd
、言語やロケールの設定に関係なく、日付は正しく処理されるといつも思っていました。
SET LANGUAGE FRENCH; DECLARE @d DATETIME = '20130605'; SELECT @d;
ダッシュでもう一度お試しください。
この記事によると、DateTime2を使用して同じ精度のDateTimeを使用する場合は、DateTime2(3)を使用するだけです。これにより、同じ精度が得られ、バイト数が1つ少なくなり、範囲が拡張されます。
Select ValidUntil + 1
from Documents
上記のSQLは、DateTime2フィールドでは機能しません。返され、エラー「オペランドタイプの競合:datetime2はintと互換性がありません」
翌日を取得するために1を追加することは、開発者が何年もの間日付で行ってきたものです。現在、Microsoftには、この単純な機能を処理できない非常に新しいdatetime2フィールドがあります。
「古いタイプよりも悪いこの新しいタイプを使ってみよう」とは思わない!
datetime
、datetime2
データ型とSQLデータ型の両方がSQL Server 2008で導入されたことです。また、1日のドット以来存在していOperand type clash: date is incompatible with int
たdate
型からも取得できます。3つのデータ型はすべて問題なく動作しdateadd(dd, 1, ...)
ます。