在SQL Server数据库中,DATETIME和SMALLDATETIME值是以整数存储的。然而,与整数不同的是,它们不能直接地进行数学运算。尽管如此,有时候还是需要在日期/时间值中添加或减去一个时间间隔。比如,你可能想在一值上加一些月数或天数,或者甚至可能是小时数。
你甚至可能想比较两个日期/时间值以便确定它们之间的时间间隔,如相差的天数或年数。为了简化这些类型的计算,Transact-SQL支持两个重要的日期/时间方法:DATEADD和DATEDIFF。 在关于DATETIME值这一系列文章的第四部分,我阐述了如何使用这两个方法并举例说明它们是如何工作的。为了演示这些方法,我使用了下面的T……
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
 
                        TechTarget
官方微博
 
                        TechTarget中国
在SQL Server数据库中,DATETIME和SMALLDATETIME值是以整数存储的。然而,与整数不同的是,它们不能直接地进行数学运算。尽管如此,有时候还是需要在日期/时间值中添加或减去一个时间间隔。比如,你可能想在一值上加一些月数或天数,或者甚至可能是小时数。你甚至可能想比较两个日期/时间值以便确定它们之间的时间间隔,如相差的天数或年数。为了简化这些类型的计算,Transact-SQL支持两个重要的日期/时间方法:DATEADD和DATEDIFF。
在关于DATETIME值这一系列文章的第四部分,我阐述了如何使用这两个方法并举例说明它们是如何工作的。为了演示这些方法,我使用了下面的Transact-SQL代码在AdventureWorks示例数据库中创建了一个Sales.Orders表:
| USE AdventureWorks GO IF EXISTS (SELECT table_name FROM information_schema.tables WHERE table_schema = 'Sales' AND table_name = 'Orders') DROP TABLE Sales.Orders GO CREATE TABLE Sales.Orders ( OrderID INT NOT NULL, OrderDate DATETIME NOT NULL, DelivDate DATETIME NOT NULL ) GO INSERT INTO Sales.Orders VALUES(1001, GETDATE(), '2008-09-08 18:27:10.750') | 
表的定义包含了OrderDate和DelivDate字段,两者都是DATETIME数据类型。在我创建了表之后,我在表中插入了一行用于测试DATEADD和DATEDIFF方法的数据。
使用DATEADD方法
在一些情况下,你可能想添加一个时间间隔到DATETIME或SMADDDATETIME值中——或者减去一个时间间隔。比如,你可能需要在一个指定的日期中增加或减去一个月。你可以使用DATEADD方法来执行这个计算。这个方法运用了下面的语法:
| DATEADD(<date/time_part>, <number>, <date>) | 
<date/time_part>占位符指的是日期/时间值中增加或减少的增量/余差(如日或月)。下表列出了可以使用的日期/时间部分,以及代表这些部分的缩写:
| Date/time part | Abbreviations | 
| year | yy, yyyy | 
| quarter | qq, q | 
| month | mm, m | 
| day of year | dy, y | 
| day | dd, d | 
| week | wk, ww | 
| weekday | dw | 
| hour | hh | 
| minute | mi, n | 
| second | ss, s | 
| millisecond | ms | 
比如,如果你想在一个日期/时间值中增加一小时,可以使用hh缩写。在某些情况下,日期/时间部分支持两个缩写,如周可以用wk或ww支持。
<number>占位符指的是所增加的数值(一个整数)。比如,如果在日期中增加10天,就是10。但是,注意,如果是减去时间间隔,它必须是一个负整数。比如,从天数中减去10,就必须是-10。
<date>占位符指的是增加或减少的指定间隔的日期/时间值。它可能是一个日期/时间格式的字符串值,或者是方法返回的一个日期/时间值,又或者是常见的DATETIME或SMALLDATETIME字段。
让我们举例来说明它是如何工作的。在下面的SELECT语句中,我增加三个月到Sales.Orders表中OrderDate值:
| SELECT OrderDate, DATEADD(mm, 3, OrderDate) AS NewDate FROM Sales.Orders WHERE OrderID = 1001 | 
注意,SELECT列表使用了DATEADD方法。这个方法有三个参数:mm指月,3指月数,而OrderDate是一个DATETIME值。因此,当查询返回值时,每个OrderDate值都会增加三个月时间,如下的结果所示:
| OrderDate | NewDate | 
| 2008-08-27 13:36:16.280 | 2008-11-27 13:36:16.280 | 
如上所示,日期August 27已经被改为November 27。而且,这样的运算还不仅限于日期。下面我在OrderDate值中增加三个小时:
| SELECT OrderDate, DATEADD(hh, 3, OrderDate) AS NewTime FROM Sales.Orders WHERE OrderID = 1001 | 
DATEADD的第一个参数现在是hh,而不是mm,因此,只有小时被改变了,如下结果所示:
| OrderDate | NewTime | 
| 2008-08-27 13:36:16.280 | 2008-08-27 16:36:16.280 | 
日期/时间值也可以减去一定的日期或时间间隔。在下例中,我从OrderDate值中减去了三天:
| SELECT OrderDate, DATEADD(dd, -3, OrderDate) AS PastDate FROM Sales.Orders WHERE OrderID = 1001 | 
注意,DATEADD的第一个参数现在是dd。同时,注意,第二个参数是一个负数,这意味着将有三天被减去,如下所示:
| OrderDate | PastDate | 
| 2008-08-27 13:36:16.280 | 2008-08-24 13:36:16.280 | 
这样,新的日期是August 24而不是August 27。
这样,上面的例子演示如何在从数据库查询到日期/时间值后再对它进行修改。而DATEADD方法同样也可以用来插入日期/时间数据。因为DATEADD方法返回一个DATETIME值。(如果所提供的日期对应的方法是SMALLDATETIME,那么它将返回一个SMALLDATETIME值。)在下面的例子中,我添加了一行数据到Sales.Orders表中,然后使用SELECT语句来检索这个行:
| INSERT INTO Sales.Orders VALUES(1002, GETDATE(), DATEADD(dd, 10, GETDATE())) GO SELECT * FROM Sales.Orders WHERE OrderID = 1002 | 
注意,VALUES子句包含了表中每个字段的值。对于OrderDate值,我使用GETDATE()方法来获取当前的日期和时间。对于DelivDate字段,我使用DATEADD方法以及相应的三个参数。第一个参数dd表示将要添加到日期中的是天数。第二个参数10意味着将添加10天到日期中。最后,第三个参数是GETDATE方法。因此,10天将添加到目前的日期和时间中并插入到DelivDate字段。这就是SELECT语句生成的结果:
| OrderID | OrderDate | DelivDate | 
| 1002 | 2008-08-27 13:40:22.357 | 2008-09-06 13:40:22.357 | 
正如所期待的,DelivDate值比OrderDate晚10天。
现在让我们来检测一个使用了DATEADD方法的UPDATE语句。在下面的语句中,我从DelivDate值中减去了三天,然后显示了结果:
| UPDATE Sales.Orders SET DelivDate = DATEADD(dd, -3, DelivDate) WHERE OrderID = 1002 GO SELECT * FROM Sales.Orders WHERE OrderID = 1002 | 
这次我在SET子句中使用了DATEADD——我将DelivDate值设为DATEADD方法返回的结果。这个方法指定天数(dd)为第一个参数,-3为第二个参数,而DelivDate字段为第三个参数。这就意味着该方法将返回一个比原始日期早三天的日期,并将DelivDate设置为新的日期,如下结果显示:
| OrderID | OrderDate | DelivDate | 
| 1002 | 2008-08-27 13:40:22.357 | 2008-09-03 13:40:22.357 | 
你应该记得,INSERT语句(在前一个例子)添加了一个DelivDate值为September 6的行。但是,这个值现在是September 3,比原来早了三天。
翻译
TechTarget中国特约技术编辑,某高校计算机科学专业教师和网络实验室负责人,曾任职某网络国际厂商,关注数据中心、开发运维、数据库及软件开发技术。有多本关于思科数据中心和虚拟化技术的译著,如《思科绿色数据中心建设与管理》和《基于IP的能源管理》等。
相关推荐
- 
            云端SQL Server高可用性最佳做法与内部部署相比,在云端运行SQL Server可为数据库软件用户提供更多的灵活性和可扩展性,也可能更省钱。但云 […] 
- 
            绘制数据关系图的利器:SQL Server 图像数据库工具SQL Server 2017新增了图形数据库功能,你可以使用图结构来表示不同数据元素之间的关系。 
- 
            如何在Azure部署时选择合适的SQL Server?想要在Azure上运行SQL Server,企业一般会面临两种选择:在Azure虚拟机上安装SQL Server或使用Azure SQL Database。 
- 
            Linux支持的引入 推动了SQL Server 2016集成服务的发展随着SQL Server的不断发展,集成服务也在发生相应的变化。在最新的SSIS更新中,增加Linux支持和SQL Server 2016升级向导。 
 
                        
