2011-01-24 4 views
1

У меня есть кластеризованный индекс, который находится над несколькими полями. Одно из этих полей - CustomerID. У меня есть курсор, который читается из этой таблицы, а затем обновляет CustomerID. Проблема в том, что он вызывает бесконечный цикл. Я предполагаю, что когда он изменяет поле customerid, кластеризованный индекс изменяется и таблица реструктурируется для индекса. Эта модификация, по-видимому, недействительна для моего курсора, поэтому FETCH NEXT FROM Cursor никогда не доходит до конца.Обновление кластерного индекса из проблемы с курсором

FETCH NEXT FROM AccountSoftwareRegCursor 
INTO @CurrentAccountSoftwareRegUId 

    WHILE (@@FETCH_STATUS = 0) 
    BEGIN 

    UPDATE 
     Licensing.AccountSoftwareRegistration 
    SET 
     AccountUid = @ToAccountUid, 
     CompanyId = @ToCompanyId, 
     UpdatedBy = isnull(@UpdatedBy,'Asset Transfer'), 
     UpdatedByAccount = @UpdatedByAccount, 
     UpdatedOn = GETUTCDATE() 
    WHERE 
     AccountSoftwareRegUid = @CurrentAccountSoftwareRegUId 

Есть ли команда, я могу выдать, чтобы остановить таблицу из не обновления таблицы для кластерного индекса только после завершения курсора?

+1

Можете ли вы показать нам весь код, от населенности вашего курсора до его закрытия ?; Я имею в виду, что, как мы знаем, вы можете пропустить какой-либо другой оператор, который заставляет ваш курсор перемещаться по бесконечному циклу. – Lamak

+1

Для этого в курсоре нет НИКАКОГО ПРИЧИНА. Это должна быть операция на основе набора. Пожалуйста, прочитайте: http://wiki.lessthandot.com/index.php/Cursors_and_How_to_Avoid_Them – HLGEM

+0

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

ответ

3

Если вы не можете переписать это, чтобы устранить курсор, вам нужно объявить свой курсор как STATIC.

DECLARE AccountSoftwareRegCursor CURSOR STATIC 
FOR 
SELECT... 

Из документации DECLARE CURSOR:

STATIC

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

+0

Спасибо, что отлично работало. –

+1

Хотя это технически решает проблему, я бы предложил посмотреть, что предложил Кейд ниже, не включая CustomerID в Clustered Index. Обновление кластерного индекса также каскадируется для всех некластеризованных индексов на этой таблице, что увеличивает время, необходимое для завершения операции, и потенциал для DeadLocks. –

1

В дополнение к изменению этого в операции на основе набора вместо курсора, ваш кластерный индекс, имеющий столбец, который меняется должен быть красный флаг:

Пожалуйста, ознакомьтесь с Microsoft's Clustered Index Design Guidelines

кластерный индекс должен быть unique, narrow, static and ever-increasing