存储过程中的SQL Server日期计算

时间:2013-06-27 21:25:27

标签: sql-server tsql stored-procedures

我想问下面有关下面代码的3个问题(请原谅长代码列表,我希望它包含这些行,希望它提供足够的上下文)。

请注意,此处的代码取决于执行日期。出于这个原因,我的问题涉及具有两个不同执行日期的假设情况:

  1. 2014年3月1日
  2. 2014年1月1日
  3. 我的问题是我对这部分内容的理解是否正确,即:

    A 即可。 SELECT DATEADD表达式(第1行)将:

    • 2014年3月1日上创建日期时间2014-02-31 23:59:59

    即可。第6-9行的代码:

    • 2014年3月1日上创建日期时间2014-02-01 00:00:00
    • 2014年1月1日上创建日期时间2013-02-01 00:00:00

    C 即可。第11-14行的代码:

    • 2014年3月1日上创建日期时间2015-01-30 00:00:00
    • 2014年1月1日上创建日期时间2014-01-30 00:00:00

    这种理解是否正确?

    1. SET @ldpmth = (SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0)) )
    2. SET @yr = (SELECT YEAR(@ldpmth))
    3. SET @mth = 0
    4. SET @dy = 0
    5. 
    6. SET @fysdate = (SELECT CASE WHEN MONTH(@ldpmth) >= 2 THEN
    7. DATEADD(MM, 1,CAST(CAST(@yr+@mth+@dy AS NVARCHAR(50)) AS DATETIME))
    8. ELSE DATEADD(MM, 1, CAST(CAST((@yr-1)+@mth+@dy AS NVARCHAR(50))
    9. AS DATETIME)) END ) 
    10. 
    11. SET @fyedate = (SELECT CASE WHEN MONTH(@ldpmth) >= 2 THEN
    12. DATEADD(YY, 1, CAST(CAST(@yr+@mth+@dy AS NVARCHAR(50)) AS DATETIME)) + 30
    13. ELSE  DATEADD(YY, 1, CAST(CAST((@yr-1)+@mth+@dy AS NVARCHAR(50))
    14. AS DATETIME)) + 30 END )
    

    (感谢所有到目前为止回答的人。这实际上是几年前在我的工作地点开发的(但没有记录)代码,我的任务是将其转换为客户端的工作方式。水晶报告。)

3 个答案:

答案 0 :(得分:2)

  

2014年3月1日创建日期时间2014-02-31 23:59:59

没有。 AFAIK,没有任何 dbms那么愚蠢它认为2月31日是实际日期。第1行的SQL语句将返回值'2014年2月28日23:59:59'。

您可以通过将实际日期替换为GETDATE()和guesswork来测试所有语句。例如,在第一个查询中,使用

SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,'2014-03-01'),0));
                                              ^^^^^^^^^^

您可以在本地运行SQL Server版本。 SQL Server 2008甚至可以安装在Windows XP上。但是,如果你不能忍受,那就是sqlfiddle.com。

答案 1 :(得分:0)

这可以在SQL Server Management Studio(SSMS)中轻松测试。我会回答第一个,你可以自己测试下两个。

问题:

  

一个。 DATEADD(第1行)将于2014年3月1日创建日期时间2014-02-31 23:59:59

答案:不,因为二月不可能有31天,所以无法返回'2014-02-31`

证明:

select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,'2014-03-01'),0))

Results

(No column name)
2014-02-28 23:59:59.000

答案 2 :(得分:0)

对于(B)和(C),如果您说明了您的问题,而是“我的财政年度从2月1日到1月30日(原文如此)” - 如何获取当前的开始和结束日期财政年度,我已经提出:

SET @fysdate = DATEADD(year,DATEDIFF(month,'19000201',GETDATE())/12,'19000201')

SET @fyedate = DATEADD(year,DATEDIFF(month,'19000201',GETDATE())/12,'19010131')

(请注意,这一秒发现1月31日,而不是30日。我认为这是你原来问题中的疏忽)。

但是,至于(A),正如我所指出的那样,我认为你的问题再次表达不好 - 如果你试图找到一个时期的终点并且那个时期是在日期时间定义的(而不仅仅是日期) ),构建独占上限要容易得多:

SET @ldpmth = DATEADD(month, DATEDIFF(month,0,GETDATE()),0)

此约束(用于<比较而不是<=BETWEEN)不会人为地排除任何带有23:59:59.527等时间的值。另请注意,如果财务年度结束日期计算将用于包含时间的日期时间值,我将再次建议计算独占上限,并替换19010201代替19010131

所以,总的来说,我认为我实际上没有回答你所提出的问题,但我认为我已经提供了你应该寻求的答案。