The internal storage of a DATETIME2 value
Posted
by Peter Larsson
on SQL Team
See other posts from SQL Team
or by Peter Larsson
Published on Wed, 15 Dec 2010 21:05:02 GMT
Indexed on
2010/12/16
4:13 UTC
Read the original article
Hit count: 547
Filed under:
Today I went for investigating the internal storage of DATETIME2 datatype. What I found out was that for a datetime2 value with precision 0 (seconds only), SQL Server need 6 bytes to represent the value, but stores 7 bytes.
This is because SQL Server add one byte that holds the precision for the datetime2 value.
Start with this very simple repro
declare @now datetime2(7) = '2010-12-15 21:04:03.6934231'
This is because SQL Server add one byte that holds the precision for the datetime2 value.
Start with this very simple repro
declare @now datetime2(7) = '2010-12-15 21:04:03.6934231'
select cast(cast(@now as datetime2(0)) as binary(7)),
cast(cast(@now as datetime2(1)) as binary(7)),
cast(cast(@now as datetime2(2)) as binary(7)),
cast(cast(@now as datetime2(3)) as binary(8)),
cast(cast(@now as datetime2(4)) as binary(8)),
cast(cast(@now as datetime2(5)) as binary(9)),
cast(cast(@now as datetime2(6)) as binary(9)),
cast(cast(@now as datetime2(7)) as binary(9))
Now we are going to copy and paste these binary values and investigate which value is representing what time part.
Prefix Ticks Ticks Days Days Original value
Now we are going to copy and paste these binary values and investigate which value is representing what time part.
Prefix Ticks Ticks Days Days Original value
------ ---------- ------------ ------ ------ --------------------
0x 00 442801 75844 A8330B 734120 0x00442801A8330B
0x 01 A5920B 758437 A8330B 734120 0x01A5920BA8330B
0x 02 71BA73 7584369 A8330B 734120 0x0271BA73A8330B
0x 03 6D488504 75843693 A8330B 734120 0x036D488504A8330B
0x 04 46D4342D 758436934 A8330B 734120 0x0446D4342DA8330B
0x 05 BE4A10C401 7584369342 A8330B 734120 0x05BE4A10C401A8330B
0x 06 6FEBA2A811 75843693423 A8330B 734120 0x066FEBA2A811A8330B
0x 07 57325D96B0 758436934231 A8330B 734120 0x0757325D96B0A8330B
Let us use the following color schema
Red - Prefix
Green - Time part
Blue - Day part
What you can see is that the date part is equal in all cases, which makes sense since the precision doesm't affect the datepart. What would have been fun, is datetime2(negative) just like round accepts a negative value.
-1 would mean rounding to 10 second, -2 rounding to minute, -3 rounding to 10 minutes, -4 rounding to hour and finally -5 rounding to 10 hour.
-5 is pretty useless, but if you extend this thinking to -6, -7 and so on, you could actually get a datetime2 value which is accurate to the month only. Well, enough ranting about this. Let's get back to the table above.
If you add 75844 second to midnight, you get 21:04:04, which is exactly what you got in the select statement above.
And if you look at it, it makes perfect sense that each following value is 10 times greater when the precision is increased one step too.
//Peter
Let us use the following color schema
Red - Prefix
Green - Time part
Blue - Day part
What you can see is that the date part is equal in all cases, which makes sense since the precision doesm't affect the datepart. What would have been fun, is datetime2(negative) just like round accepts a negative value.
-1 would mean rounding to 10 second, -2 rounding to minute, -3 rounding to 10 minutes, -4 rounding to hour and finally -5 rounding to 10 hour.
-5 is pretty useless, but if you extend this thinking to -6, -7 and so on, you could actually get a datetime2 value which is accurate to the month only. Well, enough ranting about this. Let's get back to the table above.
If you add 75844 second to midnight, you get 21:04:04, which is exactly what you got in the select statement above.
And if you look at it, it makes perfect sense that each following value is 10 times greater when the precision is increased one step too.
//Peter
© SQL Team or respective owner