Вложенные курсоры T-SQL некорректно выполняются - PullRequest
4 голосов
/ 30 сентября 2010

Прежде, чем я получу воинствующее изменение курсора, позвольте мне сказать, что я пытаюсь использовать вложенные курсоры, чтобы сделать то, что мне нужно сделать только один раз, но если я запустил оперативную хранимую процедуру один раз для каждого пользователя и агентства, которые у меня естьчтобы сделать это несколько сотен раз.

Я думал, что вложенный курсор в этом случае спасет меня от работы, однако, когда я запускаю этот скрипт, он проходит через внешний курсор только один раз, тогда как внутренний работает просто отличнодля этого бега.В тестовом примере внешний набор курсоров состоит из двух строк, а внутренний - около пятидесяти.Он проходит через первую строку внешнего курсора и все пятьдесят внутренних, но затем все готово.

Как видите, я сохраняю результат внешнего извлечения ('@@ 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 ]

2 голосов
/ 30 сентября 2010

Код выглядит так, как будто он должен работать. Добавьте счет в начале:

select count(*) from #users

чтобы дважды проверить количество строк в #users?

1 голос
/ 06 октября 2010

Я ценю все ответы.

В итоге я удалил внешний курсор и просто вручную запустил внутренний.Это спасло меня от ручного ввода 393 отдельных записей.Мне просто нужно было запустить сценарий три раза.

1 голос
/ 30 сентября 2010

Я согласен с Андомаром, это должно работать.Этот тестовый пример проходит через внешний цикл 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
1 голос
/ 30 сентября 2010

Я не уверен в устранении неполадок вложенного курсора, кроме того, что есть способ избавиться от него и иметь только один курсор.

Сделайте этот оператор выбора, используя перекрестное соединение:

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

Используйте это как определение курсора. Он должен иметь каждую комбинацию пользователя и агентства / субагентства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...