【澳门金沙vip】SQL Server时间类型datetime

其在数据库系统中的存储为两个4字节的整形。

  一、场景

我要做一份假的考勤记录,需批量更新考勤打卡时间,
如果我需要更改07年1月份的所有人员第一,
二次打卡时间,且产生虚似随机的一个打卡时间,第一次打卡时间范围为8:00~8:10
第二次时间范围为17:00~17:10之间

SQL datetime 日期和时间数据,可表示1753.1.1 至
9999.12.31的时间,精度为1/300秒, 约0.33秒,

1.     
创建三种数据类型char(10)、datetime、smalldatetime的表;(表结构如下面SQL)

/*
功能:按某一段时间,自动生成员工的打卡记录
设计:OK_008(wgh)
时间:2007-04-14
*/
–人事表
CREATE TABLE #Employee(EmployeeID int,ChineseName nvarchar(20))
–考勤表
CREATE TABLE #OnOffDuty(EmployeeID int,Check1 datetime,Check2 datetime,CheckDate datetime)
–虚拟人事信息
澳门金沙vip,INSERT INTO #Employee
SELECT 1,’张小名’ UNION ALL
SELECT 2,’黄大’ UNION ALL
SELECT 3,’李兵’ UNION ALL
SELECT 4,’刘达’ UNION ALL
SELECT 5,’张雷’ UNION ALL
SELECT 6,’郭小妹’ 
/*
自动生成2007年1月份的考勤打卡时间
方法:
    使用游标按员工再按日期生成打卡记录   
*/
DECLARE @BeginDate datetime
,@EndDate datetime
,@CheckDate datetime
,@EmployeeID int
,@EXECUTE_SQL nvarchar(4000)
,@For int
SELECT @BeginDate=’2007-01-01′,@EndDate=’2007-01-31′ ,@EXECUTE_SQL=”,@For=0
DECLARE CursorEmployee CURSOR FOR
SELECT EmployeeID FROM #Employee 
OPEN CursorEmployee
FETCH NEXT FROM CursorEmployee INTO @EmployeeID
WHILE @@FETCH_STATUS=0
BEGIN
  SET @CheckDate=@BeginDate
  WHILE (@CheckDate<=@EndDate)
   BEGIN
    –根据实际调整RAND()的值范围
    SELECT @EXECUTE_SQL=@EXECUTE_SQL+’INSERT INTO #OnOffDuty SELECT ‘
     +CAST(@EmployeeID AS nvarchar(20))+’,”’
     + CONVERT(nchar(10),@CheckDate,121)+’ 08:0’+SUBSTRING(CAST(RAND() AS nvarchar(20)),3,1)+”’,”’
     + CONVERT(nchar(10),@CheckDate,121)+’ 17:0’+SUBSTRING(CAST(RAND() AS nvarchar(20)),3,1)+”’,”’
     + CONVERT(nchar(10),@CheckDate,121)+””+CHAR(10)
     ,@For=@For+1
    IF (@For%40)=0  –每40行保存一次,根据实际的@EXECUTE_SQL长度来调试多少行。
     BEGIN
      EXECUTE (@EXECUTE_SQL)
      SET @EXECUTE_SQL=”
     END
    SET @CheckDate=DATEADD(day,1,@CheckDate)
   END
  FETCH NEXT FROM CursorEmployee INTO @EmployeeID
END
CLOSE CursorEmployee
DEALLOCATE CursorEmployee
IF(@EXECUTE_SQL<>”) EXECUTE (@EXECUTE_SQL)  –判断@EXECUTE_SQL是否已经执行完成
–查询结果:
SELECT B.ChineseName,A.Check1,A.Check2,A.CheckDate FROM #OnOffDuty A 
INNER JOIN  #Employee B ON B.EmployeeID=A.EmployeeID
ORDER BY A.EmployeeID,A.CheckDate
DROP TABLE #Employee,#OnOffDuty

SQL Server时间类型datetime 兼容ADO的COleDateTime.

 

原问题:姓名  第一次打卡时间   第二次打卡时间  日期
A          8:01                        17:01                   
07-01-01
B          8:04                        17:02                   
07-01-01
A          8:03                        17:07                   
07-01-02
………….

结论: 如果是SQL Server
2005,那么请你使用smalldatetime吧,数据能节约一半,虽然查询的时候看起来没什么改变;如果你是SQL
Server 2008,那么请你使用date吧,

好久没上bbs.54master了。有一朋友问了一条有关通过SQL语句自动生成打卡问题。

   CPU 时间= 0
毫秒,占用时间= 2 毫秒。

3.      索引查询的情况:

–[TestChar10]

SQL Server
分析和编译时间:

 

   CPU 时间= 0
毫秒,占用时间= 1 毫秒。

–SQL Server 2008新数据类型

你看到这些数据,是不是觉得这样的设计既浪费了存储空间,又使得这个列的索引增大,查询起来更慢,你也想使用一些其它的数据类型来代替这个datetime吧?

 

 SQL Server
执行时间:

 SQL Server
执行时间:

   CPU 时间= 0
毫秒,占用时间= 1 毫秒。

(图4:datetime)

(图2:数据空间对比)

  二、分析

在SQL Server
2005版本中保存日期的数据类型只有两种:datetime、smalldatetime,但是在SQL
Server
2008版本中新增了一些日期数据类型:time、date、smalldatetime、datetime、datetime2、
datetimeoffset,其中的date类型就能满足我们场景中的需求了,如果你幸运的在使用SQL
Server 2008的话,那么恭喜你,请使用date数据类型吧。

       但是我就比较可悲一点了,在使用SQL Server
2005的前提下,我进入了误区一、误区二。其实这也是因为自己忽略了一下基础性的东西,如果知道不同数据类型的存储空间大小,也许就很轻易的避免这样低级的错误了。

      
其实大家都是这么想的,这个方向是100%正确的,但是在写这篇文章以前,我进入了两个误区:(如果你中了下面的两个误区,那么请你看看这篇文章吧。)

date占用3个字节,它比smalldatetime的前2个字节多了1字节,所以值的范围更广了。值范围:0001-01-01
到 9999-12-31。