SQL存储过程:从开始日期到结束日期递增数月

时间:2015-06-18 14:10:44

标签: sql-server tsql date stored-procedures cursor

我试图在SQL Server中创建一个存储过程,它基本上会将给定开始日期到给定结束日期的月份增加,并将它们更新为预定义的表格。

问题: 有点像这样:

Exec MonthRunner @Start ='2014-01-01', @End = '2014-06-01'

应该给我一张这样的表格:

Date 
2014-01-01
2014-02-01
2015-03-01
2015-04-01
2015-05-01
2015-06-01

方法: 使用光标编程的循环。类似的东西:

Create Procedure MonthRunner(@Start date, @End date)
AS
DECLARE @Date date
DECLARE @getid CURSOR


SET @getid = CURSOR FOR
Select (@Start)


Set @getid 
OPEN @getid 
FETCH NEXT
FROM @getid into @Date


WHILE @@FETCH_STATUS = 0
BEGIN
SET @Date = (Select Dateadd(Month, 1, @Date))
DECLARE @sqlrun varchar(max)

SET @sqlrun= 'Update myTable' + 'Set Date=' + @Date
EXEC @sqlrun


fetch next 
from @getid into @Date
END

CLOSE @getid
DEALLOCATE @getid

到目前为止,我的结果是:

Update myTable Set Date='2014-02-01'

但是没有循环,我也不知道如何使用变量@End来终止循环。

非常感谢您的帮助! 提前谢谢,

克莱门

4 个答案:

答案 0 :(得分:0)

这可以通过递归CTE轻松完成:

;WITH cte AS (
    SELECT      @Start      AS [Month]
    UNION ALL
    SELECT      DATEADD(MONTH, 1, [Month])
    FROM        cte
    WHERE       [Month] < @End
)

SELECT  [Month]
FROM    cte
OPTION  (MAXRECURSION 0)

答案 1 :(得分:0)

我的循环类似于:

DECLARE @Start date
DECLARE @End date 
DECLARE @counter date

set @counter = @Start
    while @counter <= @End
    begin
          print 'The counter is ' + cast(@counter as char)
         set @counter = (Select Dateadd(Month, 1, @counter))
    end

您对此解决方案有何看法? (当然我必须改变文字)

答案 2 :(得分:0)

从sp

开始从开始日期到结束日期的几个月
ALTER PROCEDURE "dbo"."monthIncrementSp"
AS
    DECLARE @startDate VARCHAR(50);
    DECLARE @endDate VARCHAR(50);

    SET @startDate = '01-01-2017';
    SET @endDate = '31-12-2017';

    SELECT TOP (DATEDIFF(MONTH, CONVERT(DATE, @startDate, 105),CONVERT(DATE, @endDate, 105))+1)
    DATEADD(MONTH, ROW_NUMBER() OVER (ORDER BY name)-1, CONVERT(DATE, @startDate, 105))
    FROM sys.all_columns

答案 3 :(得分:-1)

这是一个表值函数,用于获取一个月的开头:

CREATE FUNCTION dbo.MonthBegin (   
    @date DATE = NULL
  , @offset INT = 0
)
RETURNS TABLE   
AS   
RETURN (
    SELECT D = DATEADD(m, DATEDIFF(m, 0, @date) + @offset, 0)
);

单独使用此功能并不能完全满足您的需求。将它与一组整数相结合,你可以获得很多乐趣:

DECLARE @seedDate DATE = GETDATE();

SELECT *
FROM dbo.RangeInt(-100, 100) Nums
CROSS APPLY dbo.MonthBegin(@seedDate, Nums.N) Dates;

以上示例使用TVF生成介于-100和100之间的一组数字,然后将这些数字传递给MonthBegin TVF(以及种子日期)。你也可以把这个写成基于数字表或CTE ......对你来说最熟悉/最舒服。