光标在光标内
主要问题是将行索引更改为 1,2,3..,其中 contact-id 和 type 相同。 但所有列都可以包含完全相同的数据,因为一些前雇员搞砸了并按联系人 ID 和类型更新了所有行。 不知何故,有些行没有混乱,但索引行是相同的。 这完全是一片混乱。
我尝试将内部游标与来自外部游标的变量一起使用。 但它似乎卡在了内部光标中。
查询的一部分如下所示:
Fetch NEXT FROM OUTER_CURSOR INTO @CONTACT_ID, @TYPE
While (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
DECLARE INNER_CURSOR Cursor
FOR
SELECT * FROM CONTACTS
where CONTACT_ID = @CONTACT_ID
and TYPE = @TYPE
Open INNER_CURSOR
Fetch NEXT FROM INNER_CURSOR
While (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
可能是什么问题? @@FETCH_STATUS 是否有歧义或其他什么?
编辑:如果我不在内部光标内使用此代码,一切看起来都很好:
UPDATE CONTACTS
SET INDEX_NO = @COUNTER
where current of INNER_CURSOR
编辑:这是大图片:
BEGIN TRAN
DECLARE @CONTACT_ID VARCHAR(15)
DECLARE @TYPE VARCHAR(15)
DECLARE @INDEX_NO SMALLINT
DECLARE @COUNTER SMALLINT
DECLARE @FETCH_STATUS INT
DECLARE OUTER_CURSOR CURSOR
FOR
SELECT CONTACT_ID, TYPE, INDEX_NO FROM CONTACTS
WHERE
CONTACT_ID IN (SELECT CONTACT_ID FROM dbo.CONTACTS
WHERE CONTACT_ID IN(...)
GROUP BY CONTACT_ID, TYPE, INDEX_NO
HAVING COUNT(*) > 1
OPEN OUTER_CURSOR
FETCH NEXT FROM OUTER_CURSOR INTO @CONTACT_ID, @TYPE, @INDEX_NO
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
SET @COUNTER = 1
DECLARE INNER_CURSOR CURSOR
FOR
SELECT * FROM CONTACTS
WHERE CONTACT_ID = @CONTACT_ID
AND TYPE = @TYPE
FOR UPDATE
OPEN INNER_CURSOR
FETCH NEXT FROM INNER_CURSOR
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
UPDATE CONTACTS
SET INDEX_NO = @COUNTER
WHERE CURRENT OF INNER_CURSOR
SET @COUNTER = @COUNTER + 1
FETCH NEXT FROM INNER_CURSOR
END
CLOSE INNER_CURSOR
DEALLOCATE INNER_CURSOR
FETCH NEXT FROM OUTER_CURSOR INTO @CONTACT_ID, @TYPE, @INDEX_NO
END
CLOSE OUTER_CURSOR
DEALLOCATE OUTER_CURSOR
COMMIT TRAN
Main problem is about changing the index of rows to 1,2,3.. where contact-id and type is the same. but all columns can contain exactly the same data because of some ex-employee messed up and update all rows by contact-id and type. somehow there are rows that aren't messed but index rows are same. It is total chaos.
I tried to use an inner cursor with the variables coming from the outer cursor.
But It seems that its stuck in the inner cursor.
A part of the query looks like this:
Fetch NEXT FROM OUTER_CURSOR INTO @CONTACT_ID, @TYPE
While (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
DECLARE INNER_CURSOR Cursor
FOR
SELECT * FROM CONTACTS
where CONTACT_ID = @CONTACT_ID
and TYPE = @TYPE
Open INNER_CURSOR
Fetch NEXT FROM INNER_CURSOR
While (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
What can be the problem? Is @@FETCH_STATUS ambiguous or something?
EDIT: everything looks fine if i don't use this code inside inner cursor:
UPDATE CONTACTS
SET INDEX_NO = @COUNTER
where current of INNER_CURSOR
EDIT: here is the big picture:
BEGIN TRAN
DECLARE @CONTACT_ID VARCHAR(15)
DECLARE @TYPE VARCHAR(15)
DECLARE @INDEX_NO SMALLINT
DECLARE @COUNTER SMALLINT
DECLARE @FETCH_STATUS INT
DECLARE OUTER_CURSOR CURSOR
FOR
SELECT CONTACT_ID, TYPE, INDEX_NO FROM CONTACTS
WHERE
CONTACT_ID IN (SELECT CONTACT_ID FROM dbo.CONTACTS
WHERE CONTACT_ID IN(...)
GROUP BY CONTACT_ID, TYPE, INDEX_NO
HAVING COUNT(*) > 1
OPEN OUTER_CURSOR
FETCH NEXT FROM OUTER_CURSOR INTO @CONTACT_ID, @TYPE, @INDEX_NO
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
SET @COUNTER = 1
DECLARE INNER_CURSOR CURSOR
FOR
SELECT * FROM CONTACTS
WHERE CONTACT_ID = @CONTACT_ID
AND TYPE = @TYPE
FOR UPDATE
OPEN INNER_CURSOR
FETCH NEXT FROM INNER_CURSOR
WHILE (@@FETCH_STATUS <> -1)
BEGIN
IF (@@FETCH_STATUS <> -2)
UPDATE CONTACTS
SET INDEX_NO = @COUNTER
WHERE CURRENT OF INNER_CURSOR
SET @COUNTER = @COUNTER + 1
FETCH NEXT FROM INNER_CURSOR
END
CLOSE INNER_CURSOR
DEALLOCATE INNER_CURSOR
FETCH NEXT FROM OUTER_CURSOR INTO @CONTACT_ID, @TYPE, @INDEX_NO
END
CLOSE OUTER_CURSOR
DEALLOCATE OUTER_CURSOR
COMMIT TRAN
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
你有各种各样的问题。 首先,为什么要使用特定的 @@FETCH_STATUS 值? 它应该只是@@FETCH_STATUS = 0。
其次,您没有选择内部游标进入任何东西。 我无法想象在任何情况下您都会以这种方式选择所有字段 - 将它们拼出来!
这是一个可供参考的示例。 文件夹的主键为“ClientID”,它也是 attend 的外键。 我只是打印所有参加 UID,按文件夹 ClientID 细分:
最后,您确定要在存储过程中执行类似的操作吗? 滥用存储过程是非常容易的,并且经常反映在描述问题时存在问题。 例如,我给出的示例可以使用标准选择调用更轻松地完成。
You have a variety of problems. First, why are you using your specific @@FETCH_STATUS values? It should just be @@FETCH_STATUS = 0.
Second, you are not selecting your inner Cursor into anything. And I cannot think of any circumstance where you would select all fields in this way - spell them out!
Here's a sample to go by. Folder has a primary key of "ClientID" that is also a foreign key for Attend. I'm just printing all of the Attend UIDs, broken down by Folder ClientID:
Finally, are you SURE you want to be doing something like this in a stored procedure? It is very easy to abuse stored procedures and often reflects problems in characterizing your problem. The sample I gave, for example, could be far more easily accomplished using standard select calls.
您还可以通过完全避免使用游标来避免嵌套游标问题、一般游标问题和全局变量问题。
You could also sidestep nested cursor issues, general cursor issues, and global variable issues by avoiding the cursors entirely.
你还做更多的抓取吗? 您也应该展示这些。 您只向我们展示了一半的代码。
它应该看起来像:
另外,请确保您没有将游标命名为相同...并且被调用的任何代码(检查您的触发器)不使用名称相同的游标。 我已经看到人们在堆栈的多个层中使用“theCursor”的奇怪行为。
Do you do any more fetches? You should show those as well. You're only showing us half the code.
It should look like:
Also, make sure you do not name the cursors the same... and any code (check your triggers) that gets called does not use a cursor that is named the same. I've seen odd behavior from people using 'theCursor' in multiple layers of the stack.
这听起来像是应该用 JOIN 来完成的事情。 您能与我们分享一下更大的问题吗?
嘿,我应该能够将其简化为一个陈述,但我今天还没有时间进一步研究它,而且可能无法做到。 同时,请知道您应该能够编辑内部游标的查询,以使用 ROW_NUMBER() 函数。 从那里,您可以通过对其执行 INNER JOIN 将内部游标折叠到外部游标中(您可以连接子查询)。 最后,任何 SELECT 语句都可以使用此方法转换为 UPDATE:
其中
[YourTable/Alias]
是选择查询中使用的表或别名。This smells of something that should be done with a JOIN instead. Can you share the larger problem with us?
Hey, I should be able to get this down to a single statement, but I haven't had time to play with it further yet today and may not get to. In the mean-time, know that you should be able to edit the query for your inner cursor to create the row numbers as part of the query using the ROW_NUMBER() function. From there, you can fold the inner cursor into the outer by doing an INNER JOIN on it (you can join on a sub query). Finally, any SELECT statement can be converted to an UPDATE using this method:
Where
[YourTable/Alias]
is a table or alias used in the select query.我遇到了同样的问题,
你要做的是将第二个游标声明为:
DECLARE [second_cursor] Cursor LOCAL For
您看到“CURSOR LOCAL FOR”而不是“CURSOR FOR”
I had the same problem,
what you have to do is declare the second cursor as:
DECLARE [second_cursor] Cursor LOCAL For
You see"CURSOR LOCAL FOR" instead of "CURSOR FOR"
我不完全理解“更新游标当前”的问题是什么,但可以通过对内部游标使用两次 fetch 语句来解决这个问题:
I don't fully understand what was the problem with the "update current of cursor" but it is solved by using the fetch statement twice for the inner cursor: