Ork*_*ncı 27 sql t-sql sql-server sql-server-2005 cursor
主要问题是将行的索引更改为1,2,3 ..其中contact-id和type是相同的.但是所有列都可以包含完全相同的数据,因为一些前雇员搞砸了并通过contact-id和type更新所有行.不知何故,有些行没有混乱,但索引行是相同的.这完全是混乱.
我试图使用一个带有来自外部光标的变量的内部游标.但似乎它卡在内部光标中.
查询的一部分如下所示:
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)
Run Code Online (Sandbox Code Playgroud)
可能是什么问题?是@@ FETCH_STATUS暧昧还是什么?
编辑:如果我不在内部游标内使用此代码,一切看起来很好:
UPDATE CONTACTS
SET INDEX_NO = @COUNTER
where current of INNER_CURSOR
Run Code Online (Sandbox Code Playgroud)
编辑:这是大局:
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
Run Code Online (Sandbox Code Playgroud)
Mar*_*ham 62
你有各种各样的问题.首先,为什么要使用特定的@@ FETCH_STATUS值?它应该是@@ FETCH_STATUS = 0.
其次,你不选择你的内心光标到任何东西.而且我想不出你会以这种方式选择所有领域的任何情况 - 将它们拼出来!
这是一个经过的样本.Folder的主键为"ClientID",也是Attend的外键.我只是打印所有的Attend UID,按文件夹ClientID分类:
Declare @ClientID int;
Declare @UID int;
DECLARE Cur1 CURSOR FOR
SELECT ClientID From Folder;
OPEN Cur1
FETCH NEXT FROM Cur1 INTO @ClientID;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Processing ClientID: ' + Cast(@ClientID as Varchar);
DECLARE Cur2 CURSOR FOR
SELECT UID FROM Attend Where ClientID=@ClientID;
OPEN Cur2;
FETCH NEXT FROM Cur2 INTO @UID;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Found UID: ' + Cast(@UID as Varchar);
FETCH NEXT FROM Cur2 INTO @UID;
END;
CLOSE Cur2;
DEALLOCATE Cur2;
FETCH NEXT FROM Cur1 INTO @ClientID;
END;
PRINT 'DONE';
CLOSE Cur1;
DEALLOCATE Cur1;
Run Code Online (Sandbox Code Playgroud)
最后,你SURE你想要做这样的事情在存储过程中?滥用存储过程非常容易,并且通常会反映出表征问题的问题.例如,我给出的样本使用标准选择调用可以更容易地完成.
cms*_*sjr 10
您还可以通过完全避免游标来回避嵌套游标问题,常规游标问题和全局变量问题.
declare @rowid int
declare @rowid2 int
declare @id int
declare @type varchar(10)
declare @rows int
declare @rows2 int
declare @outer table (rowid int identity(1,1), id int, type varchar(100))
declare @inner table (rowid int identity(1,1), clientid int, whatever int)
insert into @outer (id, type)
Select id, type from sometable
select @rows = count(1) from @outer
while (@rows > 0)
Begin
select top 1 @rowid = rowid, @id = id, @type = type
from @outer
insert into @innner (clientid, whatever )
select clientid whatever from contacts where contactid = @id
select @rows2 = count(1) from @inner
while (@rows2 > 0)
Begin
select top 1 /* stuff you want into some variables */
/* Other statements you want to execute */
delete from @inner where rowid = @rowid2
select @rows2 = count(1) from @inner
End
delete from @outer where rowid = @rowid
select @rows = count(1) from @outer
End
Run Code Online (Sandbox Code Playgroud)
我不完全理解“更新游标当前”的问题是什么,但通过对内部游标使用两次 fetch 语句可以解决该问题:
FETCH NEXT FROM INNER_CURSOR
WHILE (@@FETCH_STATUS <> -1)
BEGIN
UPDATE CONTACTS
SET INDEX_NO = @COUNTER
WHERE CURRENT OF INNER_CURSOR
SET @COUNTER = @COUNTER + 1
FETCH NEXT FROM INNER_CURSOR
FETCH NEXT FROM INNER_CURSOR
END
Run Code Online (Sandbox Code Playgroud)