Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 将日期添加到表的SQL循环无效_Sql Server_Tsql_While Loop - Fatal编程技术网

Sql server 将日期添加到表的SQL循环无效

Sql server 将日期添加到表的SQL循环无效,sql-server,tsql,while-loop,Sql Server,Tsql,While Loop,我有一个WHILE循环,应该循环30次,但出于某种原因,它似乎只循环15次 SQL: 当我尝试将DATEDIFF(d、@dateInsert、@dateLoopTo)更改为30时,SQL似乎可以工作 WHILE @cnt <= 30-- DATEDIFF (d, @dateInsert , @dateLoopTo ) 而@cnt在循环的每一步,您都在增加cnt和@DateInsert。因此,您正在通过2 如何将代码写得更清楚,如下所示: WHILE @cnt <= 30 而@cn

我有一个WHILE循环,应该循环30次,但出于某种原因,它似乎只循环15次

SQL:

当我尝试将DATEDIFF(d、@dateInsert、@dateLoopTo)更改为30时,SQL似乎可以工作

WHILE @cnt <= 30-- DATEDIFF (d, @dateInsert , @dateLoopTo )

而@cnt在循环的每一步,您都在增加
cnt
@DateInsert
。因此,您正在通过2

如何将代码写得更清楚,如下所示:

WHILE @cnt <= 30

而@cnt在循环的每一步,您都在增加
cnt
@DateInsert
。因此,您正在通过2

如何将代码写得更清楚,如下所示:

WHILE @cnt <= 30

当@cnt时,您递增
cnt
并递减
DATEDIFF
(在循环内部递增
@dateInsert
会导致递减差异)同时:

First iteration:  cnt = 0; DATEDIFF(d, @dateInsert , @dateLoopTo ) = 30
Second iteration: cnt = 1; DATEDIFF = 29
Third iteration:  cnt = 2; DATEDIFF = 28

..
15th iteration:   cnt = 15; DATEDIFF = 15

避免这种情况的一种方法是使用固定值:

WHILE @cnt <= 30

当@cnt时,您递增
cnt
并递减
DATEDIFF
(在循环内部递增
@dateInsert
会导致递减差异)同时:

First iteration:  cnt = 0; DATEDIFF(d, @dateInsert , @dateLoopTo ) = 30
Second iteration: cnt = 1; DATEDIFF = 29
Third iteration:  cnt = 2; DATEDIFF = 28

..
15th iteration:   cnt = 15; DATEDIFF = 15

避免这种情况的一种方法是使用固定值:

WHILE @cnt <= 30

WHILE@cnt您可以使用基于集合的方法来实现这一点,这是我建议尽可能多地使用循环的方法。要列出两个日期之间的所有日期,可以执行以下操作:

DECLARE @dateInsert date
DECLARE @dateLoopTo date
SET @dateInsert='2016-01-01'
SET @dateLoopTo='2016-01-31'

SELECT DATEADD(dd, Number, @dateInsert)
FROM
(
    SELECT TOP (DATEDIFF(dd, @dateInsert, @dateLoopTo)) 
        ROW_NUMBER() OVER (ORDER BY o.object_id) - 1 AS Number
    FROM sys.objects o
        CROSS JOIN sys.objects o2
) x

如果这是一项常见的活动,我建议在数据库中创建一个数字表(单列,用1到x的数字填充一次,其中x=大约需要数字的高度加上一点额外的数字)。同样,根据用例/场景的不同,您还可以创建一个“日期”表并进行预填充-这基本上消除了每次计算日期范围的需要。

您可以使用基于集合的方法来实现这一点,这是我建议尽可能多地使用循环的方法。要列出两个日期之间的所有日期,可以执行以下操作:

DECLARE @dateInsert date
DECLARE @dateLoopTo date
SET @dateInsert='2016-01-01'
SET @dateLoopTo='2016-01-31'

SELECT DATEADD(dd, Number, @dateInsert)
FROM
(
    SELECT TOP (DATEDIFF(dd, @dateInsert, @dateLoopTo)) 
        ROW_NUMBER() OVER (ORDER BY o.object_id) - 1 AS Number
    FROM sys.objects o
        CROSS JOIN sys.objects o2
) x
DECLARE @dateInsert date
DECLARE @dateLoopTo date
如果这是一项常见的活动,我建议在数据库中创建一个数字表(单列,用1到x的数字填充一次,其中x=大约需要数字的高度加上一点额外的数字)。同样,根据用例/场景的不同,您还可以创建一个“日期”表并进行预填充-这基本上消除了每次计算日期范围的需要

DECLARE @dateInsert date
DECLARE @dateLoopTo date
声明计数变量并在while条件中使用

DECLARE @cnt INT = 0;
SET @dateInsert='2016-01-01'
SET @dateLoopTo='2016-01-31'
DECLARE @Count INT =DATEDIFF (d, @dateInsert , @dateLoopTo )
WHILE @cnt <=  @Count
BEGIN
print CONVERT(VARCHAR(10),@dateInsert) + ' '+ CONVERT(VARCHAR(2),@cnt)
SET @dateInsert = DATEADD(d, 1,@dateInsert)
SET @cnt = @cnt + 1;
END
DECLARE@cnt INT=0;
设置@dateInsert='2016-01-01'
将@dateLoopTo='2016-01-31'
声明@Count INT=DATEDIFF(d、@dateInsert、@dateLoopTo)
而@cnt
声明计数变量并在while条件中使用

DECLARE @cnt INT = 0;
SET @dateInsert='2016-01-01'
SET @dateLoopTo='2016-01-31'
DECLARE @Count INT =DATEDIFF (d, @dateInsert , @dateLoopTo )
WHILE @cnt <=  @Count
BEGIN
print CONVERT(VARCHAR(10),@dateInsert) + ' '+ CONVERT(VARCHAR(2),@cnt)
SET @dateInsert = DATEADD(d, 1,@dateInsert)
SET @cnt = @cnt + 1;
END
DECLARE@cnt INT=0;
设置@dateInsert='2016-01-01'
将@dateLoopTo='2016-01-31'
声明@Count INT=DATEDIFF(d、@dateInsert、@dateLoopTo)
虽然@cnt这不是一个答案(因为
@Gordon Linoff
已经提供了一个答案),但这是一种无需使用
WHILE loop
、使用更多本机查询即可实现所需的方法。此变体与
@AdaTheDev
答案类似,但不使用sys表(可能是您对使用它们有限制)

这里是使用递归cte的变量

这不是一个答案(因为
@Gordon Linoff
已经提供了一个答案),而是一种不使用
WHILE loop
,使用更多本地查询来实现所需的方法。此变体与
@AdaTheDev
答案类似,但不使用sys表(可能是您对使用它们有限制)

这里是使用递归cte的变量


由于在循环中更改了
dateInsert
,我看不出
DATEDIFF(d,@dateInsert,@dateLoopTo)
在第一次迭代后仍然返回30。由于在循环中更改了
dateInsert
,我看不到
DATEDIFF(d,@dateInsert,@dateLoopTo)
在第一次迭代后仍将返回30。请注意此处。您正在使用cte进行计数,看起来它是基于集合的,但实际上它与巧妙隐藏的循环是一样的。这里要小心。您正在使用cte进行计数,看起来它是基于集合的,但实际上它与巧妙隐藏的循环是一样的。