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
我会用简单的 INSERT
和 UPDATE
语句替换这个性能杀手游标,就像这样....
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;
我在 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
我会用简单的 INSERT
和 UPDATE
语句替换这个性能杀手游标,就像这样....
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;