我在微软文档中看到了这个例子
USE AdventureWorks2012;
GO
DECLARE contact_cursor CURSOR FOR
SELECT LastName FROM Person.Person
WHERE LastName LIKE 'B%'
ORDER BY LastName;
OPEN contact_cursor;
-- Perform the first fetch.
FETCH NEXT FROM contact_cursor;
-- Check @@FETCH_STATUS to see if there are any more rows to fetch.
WHILE @@FETCH_STATUS = 0
BEGIN
-- **This is executed as long as the previous fetch succeeds.**
FETCH NEXT FROM contact_cursor;
END
CLOSE contact_cursor;
DEALLOCATE contact_cursor;
GO
我想知道并问
a)FETCH-WHILE循环内发生了什么?它似乎什么都不做,除了跳过评论。可以在不使用'INTO'
的情况下对数据执行某些操作吗?
b)如何在T-SQL中从循环内的当前行访问列数据?最好是contact_cursor.LastName
。
是的,我读过我应该工作'基于集合',而游标效率不高。但是我允许在T-SQL中进行处理(字符串manips,测试它们,最后每行更新一次),而不是在外部程序环境中,并且以一种强大的方式仔细地进行处理,它是只有几个记录,一次+测试。而且我对T-SQL完全陌生,但对SQL和许多其他东西都是旧的。 T-SQL是重要的2016年。
我不能回复评论,因为我的等级太低了。我很感激你的帮助,对此有所解释。谢谢!
答案 0 :(得分:0)
contact_cursor是一个有序的列值集合,它构成了select语句中的一行。
在这种情况下只是LastName。
如果要对所需的值执行任何操作,需要将它们提取到有序的变量列表中。请参阅您在此页面上复制到问题中的示例下方的示例:https://docs.microsoft.com/en-us/sql/t-sql/language-elements/fetch-transact-sql?view=sql-server-2017
要使用所获取的值执行某些操作,您需要记住,您已经使用已获取的第一个值进入循环。所以你要在这里完成任何工作:
WHILE @@FETCH_STATUS = 0
BEGIN
-- **Do work with previously fetched value(s) here **
-- **Fetch next
FETCH NEXT FROM contact_cursor;
END
你应该注意到逻辑上有一个小洞。如果没有下一个怎么办?您还需要对循环外的最后一个提取值进行操作。
可替换地:
-- ** Do work on first fetched value
WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM contact_cursor;
-- ** Do work on next fetched
END
您可以使用简单变量执行任何操作,您可以使用循环内的获取值。
彼得在评论中提出的最佳选择:
WHILE (1=1)
BEGIN
FETCH NEXT FROM contact_cursor;
-- ** Do work on next fetched
IF ( @@FETCH_STATUS <> 0)
BREAK;
END