我正在使用 Microsoft SQL Server,并嘗試將一些資料插入到臨時表中。然后我想使用一個while回圈來遍歷臨時表中的每一行。我不想使用游標。
請看下面的查詢:
-- 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
請有人“好心”地向我展示我的方式中的錯誤,以及如何實作這一點?
uj5u.com熱心網友回復:
出現此問題是因為 SQL Server 不@row與表中的行關聯(關聯對您來說很明顯,但 SQL Server 不是人類)。
當您遍歷 numbers1 -> @count時,它會SELECT @ABC = ABC FROM #TMP_ABC一遍又一遍地運行。沒有WHERE子句,TOP所以 SQL Server 只是每次都讀取整個表,并將變數設定為ABC它讀取的最后一個值。
相反,您應該使用游標(如果您需要回圈;根據@Larnu 的評論,通常不需要)。您已經在某處閱讀了一些錯誤資訊,即游標不好并且 while 回圈不是游標,但這些都是錯誤的。
- 要踢的壞習慣:認為 WHILE 回圈不是 CURSOR
- 不同的游標選項會產生什么影響?
- 跟蹤游標選項
- 被忽視的 T-SQL Gems(看看為什么使用游標的區域變數比您可能使用的常規型別更好)
如果您確實出于某種原因確實需要回圈,這里是一個重寫:
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
- 示例db<>fiddle
但我不確定那完成了什么SELECT ABC FROM #TMP_ABC;。
uj5u.com熱心網友回復:
使用 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/419565.html
標籤:
下一篇:無法部署具有虛擬后端的網站
