SQL Server 2008:WHILE 循环不会迭代每一行
SQL Server 2008: WHILE loop does not iterate every row
我有一个使用 while
循环的存储过程。它应该读取每条记录并给出结果。我返回了 6 条记录,这是正确的,但它打印了 6 次第 6 条记录的结果。
DECLARE @num_month float, @RowCount int, @Init int
--Get count of SubrowID
SET @RowCount = (SELECT COUNT(SubrowID)
FROM tblSubrow
WHERE SubrowID = 13)
SET @Init = 1
--Iterate each SubrowID
WHILE (@Init <= @RowCount)
BEGIN
SELECT
@num_month = SUBSTRING(CAST(DATEDIFF(DAY, s.StartDate, s.EndDate) * CAST(10 AS float) / CAST(30 AS float) / CAST(10 AS float) AS VARCHAR(10)), (CHARINDEX('.', DATEDIFF(DAY, s.StartDate, s.EndDate) * CAST(10 AS float) / CAST(30 AS float) / CAST(10 AS float), 1)), 2)
FROM
tblSubrow
WHERE
SubrowID = '13'
print @num_month
SET @Init = @Init + 1
END
您在循环内编写的查询中没有使用循环变量@Init。我认为您希望它的行为像一个 Cursor,一旦循环 运行 就会自动移动记录,没有这样的事情。
您应该找到一种方法来根据您在循环中收到的值查询 table。或者每次编写查询以获取 Top 1 值,将其放入临时 table 并在查询中包含 NOT IN 子句以查找并获取临时 [=14 中不存在的最高值=](即排除已经提取)。
你的 WHILE 循环 select 总是去 return 6 行并且你的 @num_month 变量最终将被设置为最后一个结果行,即本例中的第 6 行案例.
我不确定您的要求以及为什么您需要将其包含在 WHILE 循环中。
改为使用结果集填充 table 变量:
假设
- [tblSubrowRowid]下面是table、[tblSubrow]的主键。
- s.StartDate 和 s.EndDate 是 [tblSubrow] 中的列。 (您没有为 [tblSubrow] 添加别名。)
您对 num_month 的计算是由您的要求决定的,因为那不是您要问的。
DECLARE @updateTable AS TABLE ( [rowid] INT, [num_month] FLOAT );
INSERT INTO @updateTable
( [rowid], [num_month] )
SELECT
[tblSubrowRowid], SUBSTRING(CAST(DATEDIFF(DAY, [StartDate], [EndDate]) * CAST(10 AS float) / CAST(30 AS float) / CAST(10 AS float) AS VARCHAR(10)), (CHARINDEX('.', DATEDIFF(DAY, [StartDate], [EndDate]) * CAST(10 AS float) / CAST(30 AS float) / CAST(10 AS float), 1)), 2)
FROM
[tblSubrow]
WHERE
SubrowID = '13';
然后您可以使用@updateTable 中的数据根据需要更新[tblSubrow] 或另一个table。
永远记住,SQL 是基于集合的,最好这样使用。
我有一个使用 while
循环的存储过程。它应该读取每条记录并给出结果。我返回了 6 条记录,这是正确的,但它打印了 6 次第 6 条记录的结果。
DECLARE @num_month float, @RowCount int, @Init int
--Get count of SubrowID
SET @RowCount = (SELECT COUNT(SubrowID)
FROM tblSubrow
WHERE SubrowID = 13)
SET @Init = 1
--Iterate each SubrowID
WHILE (@Init <= @RowCount)
BEGIN
SELECT
@num_month = SUBSTRING(CAST(DATEDIFF(DAY, s.StartDate, s.EndDate) * CAST(10 AS float) / CAST(30 AS float) / CAST(10 AS float) AS VARCHAR(10)), (CHARINDEX('.', DATEDIFF(DAY, s.StartDate, s.EndDate) * CAST(10 AS float) / CAST(30 AS float) / CAST(10 AS float), 1)), 2)
FROM
tblSubrow
WHERE
SubrowID = '13'
print @num_month
SET @Init = @Init + 1
END
您在循环内编写的查询中没有使用循环变量@Init。我认为您希望它的行为像一个 Cursor,一旦循环 运行 就会自动移动记录,没有这样的事情。
您应该找到一种方法来根据您在循环中收到的值查询 table。或者每次编写查询以获取 Top 1 值,将其放入临时 table 并在查询中包含 NOT IN 子句以查找并获取临时 [=14 中不存在的最高值=](即排除已经提取)。
你的 WHILE 循环 select 总是去 return 6 行并且你的 @num_month 变量最终将被设置为最后一个结果行,即本例中的第 6 行案例.
我不确定您的要求以及为什么您需要将其包含在 WHILE 循环中。
改为使用结果集填充 table 变量:
假设
- [tblSubrowRowid]下面是table、[tblSubrow]的主键。
- s.StartDate 和 s.EndDate 是 [tblSubrow] 中的列。 (您没有为 [tblSubrow] 添加别名。)
您对 num_month 的计算是由您的要求决定的,因为那不是您要问的。
DECLARE @updateTable AS TABLE ( [rowid] INT, [num_month] FLOAT ); INSERT INTO @updateTable ( [rowid], [num_month] ) SELECT [tblSubrowRowid], SUBSTRING(CAST(DATEDIFF(DAY, [StartDate], [EndDate]) * CAST(10 AS float) / CAST(30 AS float) / CAST(10 AS float) AS VARCHAR(10)), (CHARINDEX('.', DATEDIFF(DAY, [StartDate], [EndDate]) * CAST(10 AS float) / CAST(30 AS float) / CAST(10 AS float), 1)), 2) FROM [tblSubrow] WHERE SubrowID = '13';
然后您可以使用@updateTable 中的数据根据需要更新[tblSubrow] 或另一个table。
永远记住,SQL 是基于集合的,最好这样使用。