We have seen a few new data types introduced by SQL Server 2008 in the previous posts. So far, we have examined DATE and TIME. DATETIME2 is yet another new data type that comes with SQL Server 2008.
SQL Server 2005 already has two date data types: SMALLDATETIME and DATETIME. The new data type, DATETIME2 supports a larger range of date values and has a precision up to 100 nanoseconds.
SMALLDATETIME
I am pretty sure that all of you have used this data type quite a lot. This is good for storing date/time values when we do not really need very high precision. SMALLDATETIME data type can store date values between January 1, 1900 and June 6, 2079. SMALLDATETIME values are accurate by one minute. It will ignore seconds up to 29.998 and rounds the value up to the next minute if it has 29.999 seconds or higher.
DECLARE @sdt AS SMALLDATETIME
SELECT @sdt = GETDATE()
SELECT @sdt
-- returns 2008-06-24 23:21:00
WAITFOR DELAY '00:00:10' -- wait for 10 SECONDS
SELECT @sdt = GETDATE()
SELECT @sdt
-- returns 2008-06-24 23:21:00 (even after waiting for 10 seconds)
SMALLDATETIME data type takes 4 bytes of storage. Internally, it is stored as two 2 BYTE integers, one storing the date part and the other, the time portion.
DATETIME
I think DATETIME is the DATE/TIME related data type that we use more often. I have seen people using this data type quite a lot, even when they do not really need to deal with date/time values outside the supported range of SMALLDATETIME data type. So, DATETIME seems to be more popular than SMALLDATETIME to many database developers.
DATETIME data type supports date/time values between January 1, 1753 and December 31, 9999. DATETIME values have an accuracy of around 3 milliseconds.
SELECT
CAST('2008-01-01 10:00:00.000' AS DATETIME), --2008-01-01 10:00:00.000
CAST('2008-01-01 10:00:00.001' AS DATETIME), --2008-01-01 10:00:00.000
CAST('2008-01-01 10:00:00.002' AS DATETIME), --2008-01-01 10:00:00.003
CAST('2008-01-01 10:00:00.003' AS DATETIME), --2008-01-01 10:00:00.003
CAST('2008-01-01 10:00:00.004' AS DATETIME), --2008-01-01 10:00:00.003
CAST('2008-01-01 10:00:00.005' AS DATETIME), --2008-01-01 10:00:00.007
CAST('2008-01-01 10:00:00.006' AS DATETIME), --2008-01-01 10:00:00.007
CAST('2008-01-01 10:00:00.007' AS DATETIME), --2008-01-01 10:00:00.007
CAST('2008-01-01 10:00:00.008' AS DATETIME), --2008-01-01 10:00:00.007
CAST('2008-01-01 10:00:00.009' AS DATETIME), --2008-01-01 10:00:00.010
CAST('2008-01-01 10:00:00.010' AS DATETIME) --2008-01-01 10:00:00.010
Note that '9999-12-31 23:59:59.999' is not a valid DATETIME value because it will be rounded to the next millisecond and will result in January 1, 10000, which is well beyond the range a DATETIME value can support.
DATETIME data types takes 8 bytes of storage. It is stored internally as two 4 BYTE integers, one storing the DATE part and the other storing the TIME part.
DATETIME2
DATETIME2 is a new data type introduced by SQL Server 2008. It supports better precision (up to 100 nanoseconds) and supports a larger date range (between 1 January 0001 to 31 December 9999).
There had been some discussion about its name in the
MSDN KATMAI forums. I agree that BIGDATETIME would have been much better. So SMALLDATETIME, DATETIME and BIGDATETIME falls in the same pattern as SMALLINT, INT and BIGINT and it really makes sense to me. Jamie has written a post on the
same.
PrecisionAs mentioned earlier, DATETIME2 data type supports precision up to 100 nanoseconds. You can specify the level of precision that you need, by passing an optional argument (0 to 7). Here is an example:
SELECT
CAST(sysdatetime() AS DATETIME2), --2008-06-24 23:57:53.6250000
CAST(sysdatetime() AS DATETIME2(0)),--2008-06-24 23:57:54
CAST(sysdatetime() AS DATETIME2(1)),--2008-06-24 23:57:53.6
CAST(sysdatetime() AS DATETIME2(2)),--2008-06-24 23:57:53.63
CAST(sysdatetime() AS DATETIME2(3)),--2008-06-24 23:57:53.625
CAST(sysdatetime() AS DATETIME2(4)),--2008-06-24 23:57:53.6250
CAST(sysdatetime() AS DATETIME2(5)),--2008-06-24 23:57:53.62500
CAST(sysdatetime() AS DATETIME2(6)),--2008-06-24 23:57:53.625000
CAST(sysdatetime() AS DATETIME2(7)) --2008-06-24 23:57:53.6250000
SYSDATETIME() is a new function introduced with SQL Server 2008. GETDATE() returns a DATETIME value and SYSDATETIME() returns a DATETIME2 value. Yet another new DATE/TIME function that comes with SQL Server 2008 is 'SYSUTCDATETIME()' which returns a DATETIME2 value with the current UTC time.
Storage
The storage requirements of DATETIME2 values vary based on the level of precision that you need. Values having more precision tend to use more storage space. The following example demonstrates that.
DECLARE
@dt1 AS DATETIME2 = SYSDATETIME(),
@dt2 AS DATETIME2(0) = SYSDATETIME(),
@dt3 AS DATETIME2(1) = SYSDATETIME(),
@dt4 AS DATETIME2(2) = SYSDATETIME(),
@dt5 AS DATETIME2(3) = SYSDATETIME(),
@dt6 AS DATETIME2(4) = SYSDATETIME(),
@dt7 AS DATETIME2(5) = SYSDATETIME(),
@dt8 AS DATETIME2(6) = SYSDATETIME(),
@dt9 AS DATETIME2(7) = SYSDATETIME()
SELECT
DATALENGTH(@dt1),--8 BYTES
DATALENGTH(@dt2),--6 BYTES
DATALENGTH(@dt3),--6 BYTES
DATALENGTH(@dt4),--6 BYTES
DATALENGTH(@dt5),--7 BYTES
DATALENGTH(@dt6),--7 BYTES
DATALENGTH(@dt7),--8 BYTES
DATALENGTH(@dt8),--8 BYTES
DATALENGTH(@dt9) --8 BYTES
ADO.NET SupportSQL Server 2008's DATETIME2 data type maps to ADO.NET DateTime data type. So your Visual Studio 2005 applications can pass DateTime values as arguments to stored procedures that take DATETIME2 data types and vice versa. Visual Studio 2008 has added
SqlDbType.DateTime2 which is the ADO.NET equivalent of the SQL Server DATETIME2 data type. The following .NET data types maps to SQL Server 2008's DATETIME2 data type.
- System.DateTime
- System.Data.SqlDbType.DateTime2
- System.Data.DbType.DateTime2
Enhancements to DATE/TIME Functions
The following DATE/TIME functions were enhanced with additional flags to support DATETIME2 values.
- DATEDIFF()
- DATEADD()
- DATEPART()
let us see some examples.
DATEPART()
The following flags are added to the DATEPART() function.
- ISO_WEEK / ISOWK / ISOWW
- MCS / MICROSECOND
- NANOSECOND / NS
The following example demonstrates all the flags supported by the DATEPART() function in SQL Server 2008.
DECLARE @d DATETIME2 = SYSDATETIME()
SELECT
@d, --2008-06-26 13:25:19.7656250
DATEPART(D, @d), --26
DATEPART(DAY, @d), --26
DATEPART(DD, @d), --26
DATEPART(DAYOFYEAR, @d), --178
DATEPART(DY, @d), --178
DATEPART(DW, @d), --5
DATEPART(W, @d), --5
DATEPART(WEEKDAY, @d), --5
DATEPART(HH, @d), --13
DATEPART(HOUR, @d), --13
DATEPART(ISO_WEEK, @d), --26
DATEPART(ISOWK, @d), --26
DATEPART(ISOWW, @d), --26
DATEPART(WEEK, @d), --26
DATEPART(WK, @d), --26
DATEPART(WW, @d), --26
DATEPART(M, @d), --6
DATEPART(MM, @d), --6
DATEPART(MONTH, @d), --6
DATEPART(MCS, @d), --765625
DATEPART(MICROSECOND, @d), --765625
DATEPART(MINUTE, @d), --25
DATEPART(MI, @d), --25
DATEPART(MS, @d), --765
DATEPART(MILLISECOND, @d), --765
DATEPART(N, @d), --25
DATEPART(NANOSECOND, @d), --765625000
DATEPART(NS, @d), --765625000
DATEPART(Q, @d), --2
DATEPART(QQ, @d), --2
DATEPART(QUARTER, @d), --2
DATEPART(S, @d), --19
DATEPART(SECOND, @d), --19
DATEPART(SS, @d), --19
DATEPART(Y, @d), --178
DATEPART(YEAR, @d), --2008
DATEPART(YY, @d), --2008
DATEPART(YYYY, @d) --2008
DATEADD()
The following flags were added to the DATEDIFF() function.
- microsecond / mcs
- nanosecond / ns
Let us look at an example that shows the various flags supported by the KATMAI version of DATEADD() function.
DECLARE @d DATETIME2 = SYSDATETIME()
SELECT
@d, --2008-06-26 14:41:53.5312500
DATEADD(year, 1, @d), --2009-06-26 14:41:53.5312500
DATEADD(yy, 1, @d), --2009-06-26 14:41:53.5312500
DATEADD(yyyy, 1, @d), --2009-06-26 14:41:53.5312500
DATEADD(quarter, 1, @d), --2008-09-26 14:41:53.5312500
DATEADD(qq, 1, @d), --2008-09-26 14:41:53.5312500
DATEADD(q, 1, @d), --2008-09-26 14:41:53.5312500
DATEADD(month, 1, @d), --2008-07-26 14:41:53.5312500
DATEADD(mm, 1, @d), --2008-07-26 14:41:53.5312500
DATEADD(m, 1, @d), --2008-07-26 14:41:53.5312500
DATEADD(dayofyear, 1, @d), --2008-06-27 14:41:53.5312500
DATEADD(dy, 1, @d), --2008-06-27 14:41:53.5312500
DATEADD(y, 1, @d), --2008-06-27 14:41:53.5312500
DATEADD(day, 1, @d), --2008-06-27 14:41:53.5312500
DATEADD(dd, 1, @d), --2008-06-27 14:41:53.5312500
DATEADD(d, 1, @d), --2008-06-27 14:41:53.5312500
DATEADD(week, 1, @d), --2008-07-03 14:41:53.5312500
DATEADD(wk, 1, @d), --2008-07-03 14:41:53.5312500
DATEADD(ww, 1, @d), --2008-07-03 14:41:53.5312500
DATEADD(weekday, 1, @d), --2008-06-27 14:41:53.5312500
DATEADD(dw, 1, @d), --2008-06-27 14:41:53.5312500
DATEADD(w, 1, @d), --2008-06-27 14:41:53.5312500
DATEADD(hour, 1, @d), --2008-06-26 15:41:53.5312500
DATEADD(hh, 1, @d), --2008-06-26 15:41:53.5312500
DATEADD(minute, 1, @d), --2008-06-26 14:42:53.5312500
DATEADD(mi, 1, @d), --2008-06-26 14:42:53.5312500
DATEADD(n, 1, @d), --2008-06-26 14:42:53.5312500
DATEADD(second, 5, @d), --2008-06-26 14:41:58.5312500
DATEADD(ss, 5, @d), --2008-06-26 14:41:58.5312500
DATEADD(s, 5, @d), --2008-06-26 14:41:58.5312500
DATEADD(millisecond, 100, @d), --2008-06-26 14:41:53.6312500
DATEADD(ms, 100, @d), --2008-06-26 14:41:53.6312500
DATEADD(microsecond, 1000, @d),--2008-06-26 14:41:53.5322500
DATEADD(mcs, 1000, @d), --2008-06-26 14:41:53.5322500
DATEADD(nanosecond, 10000, @d),--2008-06-26 14:41:53.5312600
DATEADD(ns, 10000, @d) --2008-06-26 14:41:53.5312600
DATEDIFF()The following flags were added to the DATEDIFF() function.
- microsecond / mcs
- nanosecond / ns
DATEDIFF() returns a signed integer (-2,147,483,648 to +2,147,483,647) and hence, if you pass two DATETIME2 values that generates a value outside the range of integers, you will get an error. For example:
DECLARE
@d1 DATETIME2 = '2008-06-26 14:41:53.5312600',
@d2 DATETIME2 = '2008-02-15 09:35:34.0156250'
SELECT
DATEDIFF(millisecond, @d2, @d1)
The above code will generate an error because the difference of milliseconds between the two DATETIME2 values is outside the range of integer data type. The following will work.
DECLARE
@d1 DATETIME2 = '2008-06-26 14:41:53.5312600',
@d2 DATETIME2 = '2008-06-26 14:41:52.0156250'
SELECT
DATEDIFF(millisecond, @d2, @d1), --1516
DATEDIFF(ms, @d2, @d1), --1516
DATEDIFF(microsecond, @d2, @d1), --1515635
DATEDIFF(mcs, @d2, @d1), --1515635
DATEDIFF(nanosecond, @d2, @d1), --1515635000
DATEDIFF(ns, @d2, @d1) --1515635000
DATETIMEOFFSETAnother DATE/TIME data type added to SQL Server 2008 is DATETIMEOFFSET. We will examine this data type in the next post.
SQL Server 2008 (KATMAI) TSQL Enhancements
- SQL Server 2008 (KATMAI) TSQL Enhancements - Part 1 - Variable initialization and Compound Assignment Operators
- SQL Server 2008 (KATMAI) TSQL Enhancements - Part 2 - Row Constructors
- SQL Server 2008 (KATMAI) TSQL Enhancements - Part 3 - New Data Type: DATE
- SQL Server 2008 (KATMAI) TSQL Enhancements - Part 4 - New Data Type: TIME
- SQL Server 2008 (KATMAI) TSQL Enhancements - Part 5 - New Data Type: DATETIME2