sql游标重复

时间:2015-04-07 13:54:58

标签: sql-server tsql cursor

我在SQL中使用的游标遇到了问题。这是我第一次尝试使用one,但它似乎无限重复第一个条目而不是迭代,我不确定为什么会这样,因为我的理解是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

3 个答案:

答案 0 :(得分:2)

在开始游标循环之前,您似乎正在进行启动提取,但是在循环中不会再次提取。在更新语句之后但在结束语句之前添加另一次提取。

update

Fetch Next

端 靠近

答案 1 :(得分:1)

我会用简单的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;

答案 2 :(得分:0)

你错过了

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