嵌套的T-SQL游标未正确执行

时间:2010-09-29 22:19:57

标签: tsql

在我获得任何好战的游标之前,让我说我正在尝试使用嵌套游标做一些我只需要做一次的事情,但是如果我为每个用户和代理商运行一次有效的存储过程我有这样做几百次。

我认为在这种情况下嵌套游标会省去一些工作,但是,当我运行这个脚本时,它只通过外部游标一次,而内部工作正好适用于该运行。在测试用例中,外部游标集由两行组成,内部游标集约有五十行。它遍历外部光标的第一行,以及内部的所有五十行,但随后就完成了。

正如您所看到的,我正在保存外部提取的结果('@@ fetch_status'),因此它不会干扰内部光标。

我看不出问题是什么(显然)。任何人都可以看到我不能做到的事情吗?

declare @fetch_user int
declare @fetch_agency int

declare user_cursor cursor for
select upn from #users

open user_cursor

fetch next from user_cursor into @upn

select @fetch_user = @@fetch_status

while @fetch_user = 0
begin

    declare agency_cursor cursor for
    select agency, subagency from agency_system where system_id = 1

    open agency_cursor

    fetch next from agency_cursor into @agency, @subagency
    select @fetch_agency = @@fetch_status

    while @fetch_agency = 0
    begin

        select @upn, @agency, @subagency

        EXEC AddUserToAgencyInRole
            @upn
            , @agency
            , @subagency
            , @system_id 
            , @role_id
            , @response output

        fetch next from agency_cursor into @agency, @subagency
        select @fetch_agency = @@fetch_status

    end

    close agency_cursor
    deallocate agency_cursor

    fetch next from user_cursor into @upn
    select @fetch_user = @@fetch_status

end

close user_cursor
deallocate user_cursor

4 个答案:

答案 0 :(得分:2)

代码看起来应该有效。在开始时计算:

select count(*) from #users

仔细检查#users中的行数?

答案 1 :(得分:1)

我不确定对嵌套游标进行故障排除,除了有办法摆脱它并且只有一个游标。

使用交叉连接制作此选择语句:

SELECT u.upn, a.agency, a.subagency
FROM #users u, agency_system a
WHERE a.system_id = 1

将其用作光标定义。它应该包含用户和代理/子代理的所有组合。

答案 2 :(得分:1)

我同意Andomar它应该工作。此测试用例每次迭代通过外循环4次,内循环两次。 (这与各个表中的行数相匹配)

set nocount on

DECLARE @upn INT, @agency INT, @subagency INT

CREATE TABLE #users (upn INT)

insert into #users select 1 union select 2 UNION select 3 UNION select 4

CREATE TABLE #agency_system(
agency INT, 
subagency INT,
system_id INT)

insert into #agency_system
select 1,1,1 UNION select 2,2,1

declare @fetch_user int
declare @fetch_agency int

declare user_cursor cursor for
select upn from #users

open user_cursor

fetch next from user_cursor into @upn
select @fetch_user = @@fetch_status

while @fetch_user = 0
begin
PRINT 'In Outer While Loop'

    declare agency_cursor cursor for
    select agency, subagency from #agency_system where system_id = 1

    open agency_cursor

    fetch next from agency_cursor into @agency, @subagency
    select @fetch_agency = @@fetch_status

    while @fetch_agency = 0
    begin
        PRINT 'In Inner While Loop'

       fetch next from agency_cursor into @agency, @subagency
        select @fetch_agency = @@fetch_status
    end

    close agency_cursor
    deallocate agency_cursor

    fetch next from user_cursor into @upn
    select @fetch_user = @@fetch_status

end

close user_cursor
deallocate user_cursor

drop TABLE #users
drop TABLE #agency_system

答案 3 :(得分:1)

我感谢所有回复。

我最终消除了外部光标,只是手动运行内部光标。这使我免于手动输入393个单独的条目。我只需要运行三次脚本。