为什么在这个 SQL While 循环中相同的值是 return?

Why is the same value being return in this SQL While Loop?

我正在使用 Microsoft SQL 服务器,并试图将一些数据插入临时 table。然后我想使用 while 循环遍历临时 table 中的每一行。我不想使用游标。

请看下面的查询:

-- Create Table

DROP TABLE IF EXISTS #TMP_ABC

CREATE TABLE #TMP_ABC

(
  [ABC] [varchar](3) NULL,
)
 
-- Insert Values
INSERT INTO [#TMP_ABC] VALUES ('AAA')
INSERT INTO [#TMP_ABC] VALUES ('BBB')
INSERT INTO [#TMP_ABC] VALUES ('CCC')
INSERT INTO [#TMP_ABC] VALUES ('DDD')
INSERT INTO [#TMP_ABC] VALUES ('EEE')
INSERT INTO [#TMP_ABC] VALUES ('FFF')
 
-- Display values

DECLARE @count INT
DECLARE @row INT
SET @row = 1;

DECLARE @ABC varchar(3)

SET @count = (SELECT COUNT(ABC) FROM #TMP_ABC)

WHILE (@row <= @count) BEGIN
    SELECT @ABC = ABC FROM #TMP_ABC
    PRINT @ABC
    SET @row += 1
END

这是查询返回的内容:

(1 row affected)
FFF
FFF
FFF
FFF
FFF
FFF

我希望返回以下内容:

(1 row affected)
AAA
BBB
CCC
DDD
EEE
FFF

请有人 'kindly' 告诉我我的方法中的错误,以及如何实现这个?

出现此问题是因为 SQL 服务器未将 @row 与 table 中的一行相关联(相关性对您来说很明显,但 SQL 服务器不是不是人类)。

当您遍历数字 1 -> @count 时,它会一遍又一遍地 运行 相同的 SELECT @ABC = ABC FROM #TMP_ABC。没有 WHERE 子句,也没有 TOP,所以 SQL 服务器每次只是读取整个 table,并将变量设置为等于最后一个 ABC 值它读到。

相反,您应该使用游标(如果您需要循环;根据 ,通常不需要)。您已经在某处读到一些错误信息,说游标不好,while 循环不是游标,但这些都是错误的。

如果您确实出于某种原因确实需要循环,请重写:

CREATE TABLE #TMP_ABC(ABC varchar(3));

INSERT INTO #TMP_ABC(ABC) VALUES 
  ('AAA'),('BBB'),('CCC'),('DDD'),('EEE'),('FFF');
  
DECLARE @ABC varchar(3), @c cursor;
    
SET @c = cursor LOCAL FAST_FORWARD
    FOR SELECT ABC FROM #TMP_ABC;

OPEN @c;
FETCH NEXT FROM @c INTO @ABC;

WHILE @@FETCH_STATUS = 0
BEGIN
  PRINT @ABC;
  FETCH NEXT FROM @c INTO @ABC;
END

输出:

AAA
BBB
CCC
DDD
EEE
FFF

但我不确定 SELECT ABC FROM #TMP_ABC; 完成了什么。

使用 ROW_NUMBER() 函数并通过循环中 WHERE 子句中的变量传递值。

--Create another Temp table
CREATE table #Tem_abc (r int , abc varchar(3));

--Add Row number

insert into #Tem_abc
select ROW_NUMBER() over( order by ABC) as r,*
from #TMP_ABC;

--Use the loop
DECLARE @count INT;
DECLARE @row INT;
SET @row = 1;
DECLARE @ABC varchar(3);
SET @count = (SELECT COUNT(ABC) FROM #TMP_ABC);
--SET @count = (SELECT max(r) FROM #Tem_abc);

WHILE (@row <= @count) BEGIN
    
    SELECT @ABC = ABC FROM #Tem_abc where @row = r;
     PRINT @ABC;
    SET @row += 1;
END