----DATETIME 和SMALLDATETIME的内部存储与我们输入的或者显示的是完全不一样的。具体的不多说了
----看下面的演示
--1.datetime的内部存储
declare @dt datetime
set @dt= current_timestamp
---datetime在数据库中是以8字节存储的前4个存储的是以1900-01-01为基准算出来的天---数,后4位存储的是午夜0点之后的时钟周期数,每个时钟周期是1/300秒,即3.33毫秒。
select @dt as dt
/*结果
dt
-----------------------
2010-05-06 16:18:34.543
(1 行受影响)
*/
select convert(varbinary(8),@dt) as dtbinary --转化为存储的进制字符串
/*结果
dtbinary
------------------
0x00009D6E010CC61B
*/
--取前4位转化为天数,下面2条语句的执行结果应该是一样的
select convert(int,substring(convert(varbinary(8),@dt),1,4)) as dtday1
select datediff(day,0,@dt) as dtday2
/*结果
dtday1
-----------
40302
(1 行受影响)
dtday2
-----------
40302
*/
---取后4位转化秒数,下面2条语句的执行结果应该是一样的
select convert(int,substring(convert(varbinary(8),@dt),5,4))/300 as dts1 --时钟周期数/300 为秒数
select datediff(s,convert(char(10),@dt,112),@dt) as dts1
/*结果
dts1
-----------
58714
(1 行受影响)
dts1
-----------
58714
(1 行受影响)
*/
--2.smalldatetime的内部存储
declare @sdt smalldatetime
set @sdt= current_timestamp
---smalldatetime 数据类型存储天的日期和时间,但精确度低于datetime。数据库引擎将smalldatetime 值存储为两个2 字节的整数。
---第一个2 字节存储1900 年1 月1 日后的天数。另外一个2 字节存储午夜后经过的分钟数。
select @sdt as sdt
/*结果
sdt
-----------------------
2010-05-06 16:19:00
(1 行受影响)
*/
select convert(varbinary(4),@sdt) as sdtbinary--转化为存储的进制字符串
/*结果
sdtbinary
----------
0x9D6E03D3
(1 行受影响)
*/
--取前2位转化为天数,下面2条语句的执行结果应该是一样的
select convert(int,substring(convert(varbinary(8),@sdt),1,2)) as sdtday1
select datediff(day,0,@sdt) as sdtday1
/*结果
sdtday1
-----------
40302
(1 行受影响)
sdtday1
-----------
40302
(1 行受影响)
*/
---取后2位为分钟数,下面2条语句的执行结果应该是一样的
select convert(int,substring(convert(varbinary(8),@sdt),3,2)) as sdtm1 --午夜以后的分钟数
select datediff(mi,convert(char(10),@sdt,112),@sdt) as sdtm2
/*结果
sdtm1
-----------
979
(1 行受影响)
sdtm2
-----------
979
(1 行受影响)
*/