この記事では、日時の主な違いについて説明します およびdatetime2 SQLServerのデータ型。
どちらを使用するかわからない場合は、 datetime2を使用してください (以下の利点を参照してください。)
これら2つのタイプの主な違いの概要を示す表を次に示します。
機能 | 日時 | datetime2 |
---|---|---|
SQL準拠(ANSIおよびISO 8601) | いいえ | はい |
日付範囲 | 1753-01-01から9999-12-31 | 0001-01-01から9999-12-31 |
時間範囲 | 00:00:00から23:59:59.997 | 00:00:00から23:59:59.9999999 |
文字の長さ | 最小19ポジション 最大23ポジション | 最小19ポジション 最大27ポジション |
ストレージサイズ | 8バイト | 精度に応じて6〜8バイト* *精度を格納するためのプラス1バイト |
精度 | .000、.003、または.007秒の増分に丸められます | 100ナノ秒 |
ユーザー定義の分数秒精度 | いいえ | はい |
タイムゾーンオフセット | なし | なし |
タイムゾーンオフセットの認識と保存 | いいえ | いいえ |
夏時間対応 | いいえ | いいえ |
「datetime2」の利点
上記の表に示されているように、 datetime2 タイプには、日時よりも多くの利点があります 、含む:
- より広い日付範囲
- デフォルトの分数精度が大きい
- オプションのユーザー指定の精度
- datetime と同じ小数点以下の桁数を使用する場合でも、より高い精度 (つまり3)
- datetime と同じ小数点以下の桁数を使用すると、ストレージサイズが小さくなります 、しかも精度が高い*
- datetimeより2バイト少ないストレージを使用するオプション (精度は低くなりますが)*
- SQL標準(ANSIおよびISO 8601)に準拠
*場合によってはdatetime2 valueは、精度を格納するために追加のバイトを使用します。これにより、 datetimeと同じストレージサイズになります。 同じ小数点以下の桁数を使用する場合。これについてもっと知るために読んでください。
「datetime」と「datetime2」のどちらを使用する必要がありますか?
Microsoftはdatetime2を推奨しています 日時以上 新しい仕事のために(そして上記と同じ理由で)
したがって、 datetime2を使用する必要があります 、特別な理由がない限り(レガシーシステムでの作業など)。
例1-基本的な比較
日時の基本的な違いを示す簡単な例を次に示します。 およびdatetime2 。
DECLARE @thedatetime2 datetime2(7), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5555555'; SET @thedatetime = @thedatetime2; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
結果:
+-----------------------------+-------------------------+ | datetime2 | datetime | |-----------------------------+-------------------------| | 2025-05-21 10:15:30.5555555 | 2025-05-21 10:15:30.557 | +-----------------------------+-------------------------+
ここでは、日時を設定します datetime2と同じ値に変数 変数。これにより、値が datetimeに変換されます その後、SELECT
を使用できます 結果を確認するためのステートメント。
この場合、 datetime2 変数は7のスケールを使用します。これは、小数点以下7桁を意味します。 日時 一方、値は小数点以下3桁のみを使用し、最後の小数桁は切り上げられます(このデータ型は、小数秒を.000、.003、または.007秒の増分に丸めるため)。
例2–小数点以下3桁の使用
datetime2を減らすと 3にスケールします( dateime に一致させるため) )、これが何が起こるかです。
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5555555'; SET @thedatetime = @thedatetime2; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
結果:
+-------------------------+-------------------------+ | datetime2 | datetime | |-------------------------+-------------------------| | 2025-05-21 10:15:30.556 | 2025-05-21 10:15:30.557 | +-------------------------+-------------------------+
つまり、 datetime2 この場合、値も切り上げられます。ただし、 556 に切り上げられるだけです。 – 557 にはジャンプしません 日時のように 値はありません。
もちろん、 datetime2の唯一の理由は 値が切り上げられるのは、次の桁が5以上であるためです。次の桁を減らすと、丸めは実行されません。
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5554444'; SET @thedatetime = @thedatetime2; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
結果:
+-------------------------+-------------------------+ | datetime2 | datetime | |-------------------------+-------------------------| | 2025-05-21 10:15:30.555 | 2025-05-21 10:15:30.557 | +-------------------------+-------------------------+
ただし、日時 値は引き続き切り上げられます。
例3–文字列リテラルからの値の設定
前の例では、 dateime 値は、 datetime2と同じ値に設定することによって割り当てられました 価値。これを行うと、SQL Serverは、データが新しいデータ型に「適合する」ために暗黙的な変換を実行します。
ただし、同じ文字列リテラルを datetimeに割り当てようとすると datetime2に割り当てた変数 、エラーが発生します:
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5554444'; SET @thedatetime = '2025-05-21 10:15:30.5554444'; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
結果:
Msg 241, Level 16, State 1, Line 5 Conversion failed when converting date and/or time from character string.
これは、日時が原因です 小数秒が3秒以下の文字列リテラルのみを受け入れます。
したがって、この問題を克服するには、小数部分を小数点以下3桁(またはそれ以下)に減らす必要があります。
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5554444'; SET @thedatetime = '2025-05-21 10:15:30.555'; SELECT @thedatetime2 AS 'datetime2', @thedatetime AS 'datetime';
結果:
+-------------------------+-------------------------+ | datetime2 | datetime | |-------------------------+-------------------------| | 2025-05-21 10:15:30.555 | 2025-05-21 10:15:30.557 | +-------------------------+-------------------------+
datetime2 スケール3を使用している場合でも、タイプにはこの制限はありません。
例4–ストレージサイズ
日時 データ型のストレージサイズは8バイトに固定されています。
datetime2 一方、精度に応じて、6、7、または8バイトのいずれかになります。
小数点以下3桁を使用する場合、 datetime2 使用するのはわずか7バイトです。つまり、 datetimeよりも少ないストレージスペースを使用します。 (より正確に)
ただし、Microsoftは、 datetime2 typeは、精度を格納するために1バイト余分に使用します。したがって、この場合、8バイトを使用します。したがって、7、8、または9バイトのいずれかを使用すると言うことで、前のステートメントを修正できます。
ただし、これはおそらく、テーブルに格納するか変数に格納するか、およびバイナリ定数に変換するかどうかによって異なります。
DATALENGTH()
を使用するとどうなりますか 各値に使用されたバイト数を返す関数:
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5554444'; SET @thedatetime = @thedatetime2; SELECT DATALENGTH(@thedatetime2) AS 'datetime2', DATALENGTH(@thedatetime) AS 'datetime';
結果
+-------------+------------+ | datetime2 | datetime | |-------------+------------| | 7 | 8 | +-------------+------------+
しかし、それらを varbinaryに変換すると 、次のようになります:
DECLARE @thedatetime2 datetime2(3), @thedatetime datetime; SET @thedatetime2 = '2025-05-21 10:15:30.5554444'; SET @thedatetime = @thedatetime2; SELECT DATALENGTH(CONVERT(VARBINARY(16),@thedatetime2)) AS 'datetime2', DATALENGTH(CONVERT(VARBINARY(16),@thedatetime)) AS 'datetime';
結果
+-------------+------------+ | datetime2 | datetime | |-------------+------------| | 8 | 8 | +-------------+------------+
つまり、 datetime2 varbinaryに変換されるときに余分なバイトを使用します 、したがって、日時と同じストレージサイズになります 。
ただし、次の例は、データがデータベース列に格納されている場合、 datetime2の長さが7バイトになることを示しています。 日時の場合は8バイト 。
datetime2を保存する場合 データベース内の値の場合、列定義には精度が含まれます。この場合、各行の値は精度を格納するために余分なバイトを必要とせず、 datetime2 と言うことができます 日時よりも少ないストレージスペースを使用します 同じ小数秒数を使用する場合。
例5–保存されたデータのストレージサイズ
この例では、データベースを作成し、COL_LENGTH
を使用します 各列の長さをバイト単位で返します。次に、 datetime2を挿入します および日時 値を入力し、DBCC PAGE()
を使用します ページファイル内の実際のデータの長さを検索します。これは、各データ型がデータベースに保存されるときに使用するストレージスペースを示しています。
データベースを作成します:
CREATE DATABASE CompareTypes;
テーブルを作成します:
USE CompareTypes; CREATE TABLE Datetime2vsDatetime ( TheDateTime datetime, TheDateTime2 datetime2(3) );
この場合、2つの列を作成します。1つは日時です 列ともう1つはdatetime2 列。
列の長さを確認する
各列の長さ(バイト単位)を確認してください:
SELECT COL_LENGTH ( 'dbo.Datetime2vsDatetime' , 'TheDateTime2' ) AS 'datetime2', COL_LENGTH ( 'dbo.Datetime2vsDatetime' , 'TheDateTime' ) AS 'datetime';
結果:
+-------------+------------+ | datetime2 | datetime | |-------------+------------| | 7 | 8 | +-------------+------------+
したがって、 datetime2 datetime と比較して、列の長さは7バイトです。 の長さは8バイトです。
データを挿入
次に、SQLServerに保存された実際の日付と時刻の値のストレージサイズを見てみましょう。 DBCC PAGE()
を使用できます データファイルの実際のページを検査します。
ただし、最初に、列にデータを挿入する必要があります。
データの挿入:
DECLARE @thedatetime2 datetime2 = '2025-05-21 10:15:30.5554444'; INSERT INTO Datetime2vsDatetime ( TheDateTime, TheDateTime2 ) SELECT @thedatetime2, @thedatetime2;
データを選択します(確認するためだけに):
SELECT * FROM Datetime2vsDatetime;
結果:
+-------------------------+-------------------------+ | TheDateTime | TheDateTime2 | |-------------------------+-------------------------| | 2025-05-21 10:15:30.557 | 2025-05-21 10:15:30.555 | +-------------------------+-------------------------+
DBCC PAGE()の使用
ここでDBCC PAGE()
を使用します データファイルの実際のページを検査します。
まず、DBCC IND()
を使用します PagePIDを見つけるには:
DBCC IND('CompareTypes', 'dbo.Datetime2vsDatetime', 0);
結果(垂直出力を使用):
-[ RECORD 1 ]------------------------- PageFID | 1 PagePID | 307 IAMFID | NULL IAMPID | NULL ObjectID | 885578193 IndexID | 0 PartitionNumber | 1 PartitionID | 72057594042974208 iam_chain_type | In-row data PageType | 10 IndexLevel | NULL NextPageFID | 0 NextPagePID | 0 PrevPageFID | 0 PrevPagePID | 0 -[ RECORD 2 ]------------------------- PageFID | 1 PagePID | 320 IAMFID | 1 IAMPID | 307 ObjectID | 885578193 IndexID | 0 PartitionNumber | 1 PartitionID | 72057594042974208 iam_chain_type | In-row data PageType | 1 IndexLevel | 0 NextPageFID | 0 NextPagePID | 0 PrevPageFID | 0 PrevPagePID | 0
これにより、2つのレコードが返されます。 PageType of 1(2番目のレコード)に関心があります。そのレコードからPagePIDが必要です。この場合、PagePIDは 320 です。 。
これで、そのPagePIDを取得して、次の場所で使用できます。
DBCC TRACEON(3604, -1); DBCC PAGE(CompareTypes, 1, 320, 3);
これにより大量のデータが生成されますが、主に次の部分に関心があります。
Slot 0 Column 1 Offset 0x4 Length 8 Length (physical) 8 TheDateTime = 2025-05-21 10:15:30.557 Slot 0 Column 2 Offset 0xc Length 7 Length (physical) 7 TheDateTime2 = 2025-05-21 10:15:30.555
これは、日時が 8バイトの長さとdatetime2(3)を使用します データベースに保存するときに7バイトを使用します。
したがって、これは datetime2を使用する場合を補強します 日時以上 新しいデータベースを設計するとき、特にストレージサイズが懸念される場合。