sql 光标重复

sql cursor repeating

我在 SQL 中使用的光标有问题。这是我第一次尝试使用它,但它似乎是无限重复第一个条目而不是遍历,我不确定为什么会这样,因为我的理解是 fetch next 语句应该继续循环。

输出显示为:

(235 row(s) affected)
95208

(1 row(s) affected)

(1 row(s) affected)
95208

(1 row(s) affected)

(1 row(s) affected)
95208

(1 row(s) affected)
...

如有任何帮助,我们将不胜感激。

这是我的脚本:

Disable trigger tr_ttcard_ForUpdate on ttcard

-- Loop through backupBoards
declare @getTBoard cursor
declare @getTCard cursor    
declare @tcardToUpdateId int

select ttboard.id into #TempTBoards from ttboard 
join newtbackuptboards on newtbackuptboards.TBoardId = ttboard.id
where ttboard.IsActive = 0 and newtbackuptboards.id is not null

-- Update each existing tcard in backupBoards to new mappings
set @getTCard = cursor for
select ttcard.id from ttcard 
join #TempTBoards on #TempTBoards.id = ttcard.parentboard
where #TempTBoards.id is not null

open @getTCard
fetch next from @getTCard into @tcardToUpdateId
while @@FETCH_STATUS = 0
begin
    print cast(@tcardToUpdateId as nvarchar(max))
    -- create new backupCardMap linking tcardId and backupId
    insert into tbackupTCardMap (backupTCardId, backupId)
    values(
        @tcardToUpdateId,
        (select newtbackuptboards.id from newtbackuptboards 
         join ttboard on ttboard.id = newtbackuptboards.TBoardId
         join ttcard on ttcard.parentboard = ttboard.id
         where ttcard.id = @tcardToUpdateId)
    )

    update ttcard
    set backupOfTCard = @tcardToUpdateId
    where id = @tcardToUpdateId

end
close @getTCard
deallocate @getTCard

drop table #TempTBoards
go
-- Enable trigger for tcard changes
Enable trigger tr_ttcard_ForUpdate on ttcard

您似乎在开始游标循环之前进行启动提取,但没有在循环内再次提取。在更新语句之后但在结束语句之前添加另一个提取。

update

Fetch Next

结束 关闭

你错过了

fetch next from @getTCard into @tcardToUpdateId

This

尝试:

open @getTCard
fetch next from @getTCard into @tcardToUpdateId
while @@FETCH_STATUS = 0
begin
    print cast(@tcardToUpdateId as nvarchar(max))
    -- create new backupCardMap linking tcardId and backupId
    insert into tbackupTCardMap (backupTCardId, backupId)
    values(
        @tcardToUpdateId,
        (select newtbackuptboards.id from newtbackuptboards 
         join ttboard on ttboard.id = newtbackuptboards.TBoardId
         join ttcard on ttcard.parentboard = ttboard.id
         where ttcard.id = @tcardToUpdateId)
    )

    update ttcard
    set backupOfTCard = @tcardToUpdateId
    where id = @tcardToUpdateId

fetch next from @getTCard into @tcardToUpdateId --what you missed 
end
close @getTCard
deallocate @getTCard

我会用简单的 INSERTUPDATE 语句替换这个性能杀手游标,就像这样....

BEGIN TRANSACTION;

-- Update records
update ttcard
set backupOfTCard = ttboard.id
from ttboard 
join newtbackuptboards on newtbackuptboards.TBoardId = ttboard.id
join ttcard            on ttcard.parentboard = ttboard.id 
where ttboard.IsActive = 0 
  AND newtbackuptboards.id IS NOT NULL

-- Insert records
insert into tbackupTCardMap (backupTCardId, backupId)
SELECT ttboard.id , newtbackuptboards.id
from ttboard 
join newtbackuptboards on newtbackuptboards.TBoardId = ttboard.id
join ttcard            on ttcard.parentboard = ttboard.id 
where ttboard.IsActive = 0 
  AND newtbackuptboards.id IS NOT NULL

COMMIT TRANSACTION;