我有一个问题。我正在研究游标。每次在获取最后的记录并打印其数据后,光标都会打印一条附加行。要理解我的意思,请考虑以下示例示例: 我想打印仅有10位客户的信息。
USE Northwind
GO
DECLARE myCursor CURSOR
FOR SELECT TOP(10) ContactName FROM Customers
DECLARE @RowNo int,@ContactName nvarchar(30)
SET @RowNo=1
OPEN myCursor
FETCH NEXT FROM myCursor INTO @ContactName
PRINT LEFT(CAST(@rowNo as varchar) + ' ',6)+' '+ @ContactName
SET @RowNo=@RowNo+1
SET @ContactName=''
WHILE @@FETCH_STATUS=0
BEGIN
FETCH NEXT FROM myCursor INTO @ContactName
PRINT + LEFT(CAST(@rowNo as varchar) + ' ',6)+' '+ @ContactName
SET @RowNo=@RowNo+1
SET @ContactName=''
END
CLOSE myCursor
DEALLOCATE myCursor
现在看一下输出:
1 Maria Anders
2 Ana Trujillo
3 Antonio Moreno
4 Thomas Hardy
5 Christina Berglund
6 Hanna Moos
7 Frédérique Citeaux
8 Martín Sommer
9 Laurence Lebihan
10 Elizabeth Lincoln
11
行号11也已打印。它是光标中的问题还是总是发生? 有没有办法不打印这些添加数据?谢谢 (我使用sql erver 2008)
答案 0 :(得分:5)
要么...
FETCH NEXT FROM myCursor INTO @ContactName
WHILE @@FETCH_STATUS = 0
BEGIN
-- do stuff
FETCH NEXT FROM myCursor INTO @ContactName
END
或者...
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM myCursor INTO @ContactName
IF @@FETCH_STATUS = 0
BEGIN
-- do stuff
END
END
或者...
WHILE (1 = 1)
BEGIN
FETCH NEXT FROM myCursor INTO @ContactName
IF @@FETCH_STATUS <> 0
BREAK
-- do stuff
END
答案 1 :(得分:3)
您提到您正在使用SQL Server 2008.对于SQL Server 2005或更高版本,您根本不需要光标来执行您想要的操作。
select top 10 left(cast(row_number() over(order by ContactName) as varchar)+ ' ', 6) + ContactName
from Customers
答案 2 :(得分:1)
了解如何重复打印逻辑?这是指出错误的指针。你的循环应如下所示:
FETCH NEXT INTO @working_variables
WHILE @@FETCH_STATUS = 0
-- process @working_variables
FETCH NEXT INTO @working_variables
唯一重复的代码应该是FETCH NEXT
本身 - 现在的方式,最后FETCH
发生,但是PRINT
WHILE
之前的一行退出。
答案 3 :(得分:0)
记录集末尾的FETCH将@@ FETCH_STATUS设置为不为0.
FETCH NEXT命令应该是WHILE BLOCK中的最后一行。
USE Northwind
GO
DECLARE myCursor CURSOR
FOR SELECT TOP(10) ContactName FROM Customers
DECLARE @RowNo int,@ContactName nvarchar(30)
SET @RowNo=0
OPEN myCursor
FETCH NEXT FROM myCursor INTO @ContactName
WHILE @@FETCH_STATUS=0
BEGIN
SET @RowNo=@RowNo+1
SET @ContactName=''
PRINT + LEFT(CAST(@rowNo as varchar) + ' ',6)+' '+ @ContactName
FETCH NEXT FROM myCursor INTO @ContactName
END
CLOSE myCursor
DEALLOCATE myCursor
答案 4 :(得分:0)
这是一个错误的错误。这是迭代游标的更好方法,减少代码重复:
USE Northwind
GO
DECLARE myCursor CURSOR
FOR SELECT TOP(10) ContactName FROM Customers
DECLARE @RowNo int,@ContactName nvarchar(30)
SET @RowNo=0 -- initialize counters at zero, increment after the fetch/break
OPEN myCursor
WHILE 1=1 BEGIN -- start an infinite loop
FETCH NEXT FROM myCursor INTO @ContactName
IF @@FETCH_STATUS <> 0 BREAK
SET @RowNo=@RowNo+1
PRINT LEFT(CAST(@rowNo as varchar) + ' ',6)+' '+ @ContactName
END
CLOSE myCursor
DEALLOCATE myCursor
对于额外的点,使用游标变量并为小数据集声明w / FAST_FORWARD和TYPE_WARNING或STATIC。例如:
DECLARE @cursor CURSOR
SET @cursor = CURSOR FAST_FORWARD TYPE_WARNING FOR
SELECT TOP (10) ContactName FROM Customers
OPEN @cursor
......
CLOSE @cursor
DEALLOCATE @cursor
CLOSE和DEALLOCATE不是绝对必要的,因为游标变量将在批处理结束时超出范围。但是,它仍然是一个很好的形式,因为您可能会在稍后添加更多代码,并且您应该尽早释放资源。
TYPE_WARNING告诉您SQL Server隐式将请求的游标类型(FAST_FORWARD)转换为另一种类型(通常是STATIC),如果请求的类型与SELECT语句不兼容。