The translation of the article was prepared especially for students of the course "MS SQL Server Developer" .

Content
, , - , SQL Server . ( SQL Server , .)
T-SQL- , / , "05-07-2015 10:05:23.187". . , SQL Server / ( ). , , ( β , ).
DATETIME. SQL Server, DATETIME . , β . 1 1753 31 9999 . β 00:00:00.000 23:59:59.997. 1900-01-01 00:00:00.000.
. 1 1900 .
, β . , 1 1899 β -365, 1 1901 β 365. , SQL Server 0,003 . , 00:00:00.003 1, 00:00:01.000 300.
, DATETIME . , DATETIME:
DECLARE @a DATETIME = '2015-05-07 10:05:23.187'
SELECT @a;
, SELECT :
2015-05-07 10:05:23.187
, , VARBINARY:
DECLARE @a DATETIME = '2015-05-07 10:05:23.187'
SELECT CONVERT(VARBINARY(8), @a);
, -:
0x0000A49100A6463C
SQL Server DATETIME (int), 8 ( 4 ). 4 (0000A491) , 4 (00A6463C) . , SUBSTRING, :
DECLARE @a DATETIME = '2015-05-07 10:05:23.187'
SELECT SUBSTRING(CONVERT(VARBINARY(8), @a), 1, 4);
SELECT , :
0x0000A491
VARBINARY INT. DATETIME:
DECLARE @a DATETIME = '2015-05-07 10:05:23.187'
SELECT
SUBSTRING(CONVERT(VARBINARY(8), @a), 1, 4) AS DateBinary,
CAST(SUBSTRING(CONVERT(VARBINARY(8), @a), 1, 4) AS INT) AS DateInt,
SUBSTRING(CONVERT(VARBINARY(8), @a), 5, 4) AS TimeBinary,
CAST(SUBSTRING(CONVERT(VARBINARY(8), @a), 5, 4) AS INT) AS TimeInt;
SELECT:
, 1 1900 42 129 , 10 .
188 :
DECLARE @a DATETIME = '1827-12-03 22:15:11.297'
SELECT
SUBSTRING(CONVERT(VARBINARY(8), @a), 1, 4) AS DateBinary,
CAST(SUBSTRING(CONVERT(VARBINARY(8), @a), 1, 4) AS INT) AS DateInt,
SUBSTRING(CONVERT(VARBINARY(8), @a), 5, 4) AS TimeBinary,
CAST(SUBSTRING(CONVERT(VARBINARY(8), @a), 5, 4) AS INT) AS TimeInt;
1 1900 26 327 , β 24 :
( 0):
DECLARE @a DATETIME = '1900-01-01 00:00:00.000'
SELECT
SUBSTRING(CONVERT(VARBINARY(8), @a), 1, 4) AS DateBinary,
CAST(SUBSTRING(CONVERT(VARBINARY(8), @a), 1, 4) AS INT) AS DateInt,
SUBSTRING(CONVERT(VARBINARY(8), @a), 5, 4) AS TimeBinary,
CAST(SUBSTRING(CONVERT(VARBINARY(8), @a), 5, 4) AS INT) AS TimeInt;
, VARBINARY INT :
, , , DATETIME. :
DECLARE @a DATETIME = '1900-01-02 00:00:01.000'
SELECT
SUBSTRING(CONVERT(VARBINARY(8), @a), 1, 4) AS DateBinary,
CAST(SUBSTRING(CONVERT(VARBINARY(8), @a), 1, 4) AS INT) AS DateInt,
SUBSTRING(CONVERT(VARBINARY(8), @a), 5, 4) AS TimeBinary,
CAST(SUBSTRING(CONVERT(VARBINARY(8), @a), 5, 4) AS INT) AS TimeInt;
. β 1, β 300:
, DATETIME. , / SQL Server . DATETIME2, (7):
DECLARE @b DATETIME2 = '2015-05-07 10:05:23.1872436'
SELECT CONVERT(VARBINARY(10), @b);
, DATETIME:
0x07B4854E9254EC390B
DATETIME2 SQL Server (07), (EC390B), (B4854E9254), . DATE TIME . , DATE:
DECLARE @b DATE = '2015-05-07 10:05:23.1872436'
SELECT CONVERT(VARBINARY(10), @b);
, :
0xEC390B
TIME:
DECLARE @b TIME = '2015-05-07 10:05:23.1872436'
SELECT CONVERT(VARBINARY(10), @b);
, DATETIME2:
0x07B4854E9254
:
DECLARE @b DATETIME2(4) = '2015-05-07 00:00:00.0001'
SELECT CONVERT(VARBINARY(10), @b);
SELECT :
0x0401000000EC390B
, (04), , (01000000). , , SQL Server DATETIME2, DATE TIME , DATETIME, , , , , , , .
, SQL Server, , , . , /.
#2: ,
T-SQL , , , , SQL Server. , () . /. SQL Server , , , 15481099 24033389.
SQL Server , /. . british ( ) VARCHAR DATETIME:
SET LANGUAGE british;
DECLARE @a VARCHAR(20) = '19-05-2015 10:11:12';
SELECT CAST(@a AS DATETIME);
, SELECT :
2015-05-19 10:11:12.000
US English ( ) :
SET LANGUAGE us_english;
DECLARE @a VARCHAR(20) = '19-05-2015 10:11:12';
SELECT CAST(@a AS DATETIME);
SQL Server :
Msg 242, Level 16, State 3, Line 730
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Msg 242, Level 16, State 3, Line 730
varchar datetime .
: --. , SQL Server british, US English. SQL Server, US English, , , 19 , . , , :
SET LANGUAGE us_english;
DECLARE @a VARCHAR(20) = '2015-05-19 10:11:12';
SELECT CAST(@a AS DATETIME);
SELECT . british , "out-of-range".
, , , . , / , , "--". , , / :
SET LANGUAGE british;
DECLARE @a VARCHAR(20) = '2015-05-19 10:11:12';
SELECT CAST(@a AS DATETIME);
. , SQL Server . , , , "--". , , SELECT :
Msg 242, Level 16, State 3, Line 204
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Msg 242, Level 16, State 3, Line 204
varchar datetime .
, , , DATETIME2:
SET LANGUAGE british;
DECLARE @a VARCHAR(20) = '2015-05-19 10:11:12';
SELECT CAST(@a AS DATETIME2);
SELECT :
2015-05-19 10:11:12.0000000
, "--" SQL Server, DATETIME, DATETIME2.
DATETIME2, "--", , SQL Server 2008 . . , . , ISO 8601:
SET LANGUAGE british;
DECLARE @a VARCHAR(20) = '2015-05-19T10:11:12';
SELECT CAST(@a AS DATETIME);
. /, , , β , .
#3: ,
β , , , . , .
, / SQL Server . , , , , 15 2015 3:30 . ? ? SQL Server, , ? UTC? - , , .
, , . , , , , . ? , , , .
, , , . ( ).
, SQL Server 2008 DATETIMEOFFSET, / . DATETIME2 , ( UTC).
:
DECLARE @pdt DATETIMEOFFSET = SYSDATETIMEOFFSET();
SELECT @pdt;
SYSDATETIMEOFFSET DATETIMEOFFSET, , , UTC-:
2015-05-08 17:57:23.5350000 -07:00
/ UTC , . , DATENAME:
DECLARE @pdt DATETIMEOFFSET = SYSDATETIMEOFFSET();
SELECT DATENAME(tzoffset, @pdt);
, SELECT UTC:
-07:00
, DATETIMEOFFSET UTC-:
DECLARE
@utc DATETIMEOFFSET = SYSUTCDATETIME(),
@pdt DATETIMEOFFSET = SYSDATETIMEOFFSET();
SELECT @utc AS UTC, @pdt AS PDT;
, UTC (PDT) .
SQL Server 2008 SWITCHOFFSET DATETIMEOFFSET :
DECLARE @a DATETIMEOFFSET = '2015-05-08 17:57:53.3390000 -07:00';
SELECT SWITCHOFFSET(@a, '-05:00');
UTC- -07:00 -05:00 :
2015-05-08 19:57:53.3390000 -05:00
, SQL Server , , SQL Server 2008 . , SQL Server β .
, , 1 2015 :
DECLARE
@mel DATETIMEOFFSET = '2015-04-01 17:57:53.3390000 +11:00',
@sea DATETIMEOFFSET = '2015-04-01 17:57:53.3390000 -07:00';
SELECT DATEDIFF(hh, @mel, @sea);
:
18
, , 18- . 1 2015 , UTC:
DECLARE
@mel DATETIMEOFFSET = '2015-05-01 17:57:53.3390000 +11:00',
@sea DATETIMEOFFSET = '2015-05-01 17:57:53.3390000 -07:00';
SELECT DATEDIFF(hh, @mel, @sea);
:
18
18 , 17, 5 . , 5- , +10:00.
, , , . . , , . , . - , , / .
, . , . . , , .
, DATETIMEOFFSET /. / . , , .
#4: DATETIME2 DATETIME
, DATETIME2 SQL Server 2008, DATETIME , - . , , DATETIME2 DATETIME.
, :
DECLARE
@a DATETIME2 = '2015-05-12 09:47:12.5556789',
@b DATETIME = '2015-05-12 09:47:12.555';
SELECT @a AS DateTime2Type, @b AS DateTimeType;
DATETIME2 , DATETIME . .
, , SQL Server' DATETIME .003 , .. .000, .003 0,007 . (. β 1/300 = 0,0033333333333333β¦ , - .000, .003, .007, .010, .013, ...)
DATETIME2 . , , . , .555678999 .5556790, , .9999999, .
DATETIME2 , DATETIME. , DATETIME, DATETIME2. , DATETIME2 3:
DECLARE
@a DATETIME2(3) = '2015-05-12 09:47:12.5556789',
@b DATETIME = '2015-05-12 09:47:12.555';
SELECT @a AS DateTime2Type, @b AS DateTimeType;
, DATETIME2 , DATETIME.
, DATETIME2 , , , , DATETIME. , SQL Server 7 DATETIME2 8 DATETIME.
DATETIME2 8 4, 6 , 3. C DATETIME2 , , . DATETIME2 :
DECLARE
@a DATETIME2(0) = '2015-05-12 09:47:12.5556789',
@b DATETIME = '2015-05-12 09:47:12.555';
SELECT @a AS DateTime2Type, @b AS DateTimeType;
β , . :
DATETIME2 DATETIME , DATETIME2 ( 1 0001). DATETIME 1 1753 . ( 9999 , , , ).
DATE TIME, .
DECLARE
@a DATE = '2015-05-12 09:47:12.5556789',
@b TIME = '2015-05-12 09:47:12.5556789';
SELECT @a AS DateType, @b AS TimeType;
, DATE TIME /:
, , ( SQL Server 2008 , DATETIME2).
DATETIME2 , , / .NET. , DATETIME2 /, . , DATETIME.
#5: /
, . , DATETIME SMALLDATETIME. , , DATETIME2:
DECLARE
@a DATETIME2 = '2015-05-12 23:32:12.1234567',
@b DATETIME2 = '2015-05-12 23:32:12.123456789',
@c DATETIME2 = '2015-05-12 23:59:59.999999999';
SELECT '2015-05-12 23:32:12.1234567' AS OrigValue, @a AS StoredValue
UNION ALL
SELECT '2015-05-12 23:32:12.123456789', @b
UNION ALL
SELECT '2015-05-12 23:59:59.999999999', @c;
DATETIME2 7 β . , @a , @b @c :
@b , : , 123456789 1234568. @c . , , . SQL Server . , , .
, DATETIME:
DECLARE
@a DATETIME = '2015-05-12 23:59:59.996',
@b DATETIME = '2015-05-12 23:59:59.998',
@c DATETIME = '2015-05-12 23:59:59.999';
SELECT '2015-05-12 23:59:59.996' AS OrigValue, @a AS DatetimeValue
UNION ALL
SELECT '2015-05-12 23:59:59.998', @b
UNION ALL
SELECT '2015-05-12 23:59:59.999', @c;
@a , @b , @c :
, , , , DATETIME, . , SQL Server DATETIME .000, .003 .007 . , . , , , .
, . , , DATETIME2 DATETIME:
DECLARE @a DATETIME2 = '2015-05-12 23:59:59.9986789';
DECLARE @b DATETIME = @a;
SELECT @a AS Datetime2Value, @b AS DatetimeValue;
, DATETIME , :
SMALLDATETIME:
DECLARE
@a SMALLDATETIME = '2015-05-12 23:22:22',
@b SMALLDATETIME = '2015-05-12 23:22:30',
@c SMALLDATETIME = '2015-05-12 23:22:52',
@d SMALLDATETIME = '2015-05-12 23:59:52';
SELECT '2015-05-12 23:22:22' AS OrigValue, @a AS SmalldatetimeValue
UNION ALL
SELECT '2015-05-12 23:22:30', @b
UNION ALL
SELECT '2015-05-12 23:22:52', @c
UNION ALL
SELECT '2015-05-12 23:59:52', @d;
, "00" , SMALLDATETIME ,
@a : 22 , . @b , SQL Server 30 . @c. , @d , 59 , , 23 .
, , :
DECLARE @a SMALLDATETIME = '2015-05-12 23:59:29.999';
SELECT @a;
:
2015-05-13 00:00:00
, DATETIME SMALLDATIME, , . DATETIME2, .
#6:
. SQL Server 2008 , , DATE, :
DECLARE @a DATETIME2(3) = '2015-05-12 22:14:18.003';
SELECT CAST(@a AS DATE);
DATETIME2 DATE, :
2015-05-12
DATETIME DATE :
DECLARE @a DATETIME = '2015-05-12 22:14:18.003';
SELECT CAST(@a AS DATE);
TIME:
DECLARE @a DATETIME = '2015-05-12 22:14:18.003';
SELECT CAST(@a AS TIME(3));
, SELECT :
22:14:18.003
, DATE TIME. , . .
, . :
DECLARE @a DATETIME = '2015-05-12 22:14:18.003';
SELECT CAST(CONVERT(CHAR(8), @a, 112) AS DATETIME);
, , ISO (112), DATETIME, :
2015-05-12 00:00:00.000
, SQL Server . , , .
DATEADD DATEDIFF :
DECLARE @a DATETIME = '2015-05-12 22:14:18.003';
SELECT DATEADD(DAY, DATEDIFF(DAY, 0, @a), 0);
(1 1900 .) . , :
2015-05-12 00:00:00.000
SQL Server , DATETIME.
, - :
DECLARE @a DATETIME = '2015-05-12 22:14:18.003';
SELECT DATEADD(DAY, DATEDIFF(DAY, '20010101', @a), '20010101');
, 1 2001 . . , . , :
DECLARE @a DATETIME = '2015-05-12 22:14:18.003';
SELECT DATEADD(MONTH, DATEDIFF(MONTH, '20010101', @a), '20010101');
, , DAY MONTH. :
2015-05-01 00:00:00.000
, DATEADD, , :
DECLARE @a DATETIME = '2015-05-12 22:14:18.003';
SELECT DATEADD(MONTH, DATEDIFF(MONTH, '20010101', @a), '20001231');
SELECT :
2015-04-30 00:00:00.000
DATE TIME, .
#7: DATEDIFF
DATEDIFF, . , . , /:
DECLARE
@a DATETIME2(3) = '2015-12-31 23:59:59.000',
@b DATETIME2(3) = '2016-01-01 00:00:00.000';
SELECT DATEDIFF(mi, @a, @b);
SELECT 1, , , .
, :
DECLARE
@a DATETIME2(3) = '2015-12-31 23:59:59.000',
@b DATETIME2(3) = '2016-01-01 00:00:00.000';
SELECT DATEDIFF(hh, @a, @b);
SELECT , , .
:
DECLARE
@a DATETIME2(3) = '2015-12-31 23:59:59.000',
@b DATETIME2(3) = '2016-01-01 00:00:00.000';
SELECT DATEDIFF(mm, @a, @b);
, . , . .
DATEDIFF, , , , . SQL Server ( , , ), . , , . , SQL Server .
β , . , . , 60:
DECLARE
@a DATETIME2(3) = '2015-12-31 23:59:59.000',
@b DATETIME2(3) = '2016-01-01 00:00:00.000';
SELECT DATEDIFF(ss, @a, @b)/60.0000;
SELECT 0.0166666, 1, .
#8:
β . , , , - .
, , , DATETIME2:
CREATE TABLE
INSERT INTO
(101, '2015-05-06 22:43:55.123'),
(102, '2015-05-06 23:59:59.997'),
(103, '2015-05-07 00:00:00.000'),
(104, '2015-05-07 17:33:36.321'),
(105, '2015-05-08 00:00:00.000'),
(106, '2015-05-08 10:18:12.987');
7 2015 :
SELECT ColA, ColB FROM
WHERE ColB = '2015-05-07';
, , :
, DATETIME2, /, . ( ). , , , SQL Server (00:00:00) .
, , , , , .
β , :
SELECT ColA, ColB FROM
WHERE CONVERT(CHAR(8), ColB, 112) = '20150507';
SELECT , :
, , , SQL Server . SQL Server , /.
- BETWEEN:
SELECT ColA, ColB FROM
WHERE ColB BETWEEN '2015-05-06' AND '2015-05-08';
, , , :
, BETWEEN . , :
SELECT ColA, ColB FROM
WHERE ColB BETWEEN '2015-05-07' AND '2015-05-07';
SELECT :
WHERE ColB = '2015-05-07'. WHERE , WHERE, , :
WHERE ColB BETWEEN '2015-05-07 00:00:00.000' AND '2015-05-07 00:00:00.000';
, . , , .
SELECT ColA, ColB FROM
WHERE ColB BETWEEN '2015-05-07' AND '2015-05-07 23:59:59.999';
SELECT , :
DATETIME2, , :
SELECT ColA, ColB FROM
WHERE ColB >= '2015-05-07' AND colB < '2015-05-08';
SELECT , . DATETIME.
, ColB DATETIME :
CREATE TABLE
INSERT INTO
(101, '2015-05-06 22:43:55.123'),
(102, '2015-05-06 23:59:59.997'),
(103, '2015-05-07 00:00:00.000'),
(104, '2015-05-07 17:33:36.321'),
(105, '2015-05-08 00:00:00.000'),
(106, '2015-05-08 10:18:12.987');
BETWEEN :
SELECT ColA, ColB FROM
WHERE ColB BETWEEN '2015-05-07' AND '2015-05-07 23:59:59.999';
SELECT :
, BETWEEN DATETIME . SQL Server , , DATETIME. , , , . , :
SELECT ColA, ColB FROM
WHERE ColB >= '2015-05-07' AND colB < '2015-05-08';
, , :
, /.
#9: /
, - . / , .
:
DECLARE
@a DATETIME2 = '1623-01-01',
@b DATETIME = NULL;
SET @b = @a;
SELECT @b;
DATETIME2 1623- DATETIME. , DATETIME 1753 9999. , . , , , , :
Msg 242, Level 16, State 3, Line 792
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.
Msg 242, Level 16, State 3, Line 792
datetime2 datetime .
. DATETIME 1623 .
SMALLDATETIME :
DECLARE
@a DATETIME = '1823-01-01',
@b SMALLDATETIME = NULL;
SET @b = @a;
SELECT @b;
SELECT "out-of-range", SMALLDATETIME 1900 2079. .
#10:
SQL Server 2008 , . , , GETDATE GETUTCDATE.
:
SELECT GETDATE();
SELECT SYSDATETIME();
SELECT GETUTCDATE();
SELECT SYSUTCDATETIME();
SELECT SYSDATETIMEOFFSET();
, , :
2015-05-14 10:28:21.700
2015-05-14 10:28:21.7030000
2015-05-14 17:28:21.700
2015-05-14 17:28:21.7030000
2015-05-14 10:28:21.7030000 -07:00
SYSDATETIME DATETIME2. SYSUTCDATETIME , UTC-. SYSDATIMEOFFSET DATETIMEOFFSET, UTC-.
SQL Server 2008 DATENAME DATEPART /. : , UTC-. , DATENAME:
DECLARE @a DATETIMEOFFSET = '2015-05-12 19:14:38.9046722 -07:00';
SELECT
DATENAME(mcs, @a) AS Microseconds,
DATENAME(ns, @a) AS Nanoseconds,
DATENAME(tz, @a) AS TimezoneOffset;
:
DATEPART :
DECLARE @a DATETIMEOFFSET = '2015-05-12 19:14:38.9046722 -07:00';
SELECT
DATEPART(mcs, @a) AS Microseconds,
DATEPART(ns, @a) AS Nanoseconds,
DATEPART(tz, @a) AS TimezoneOffset;
:
DATENAME, , , .
/, /, /.
. : "Parameter sniffing SQL Server: ".