2014-11-06 4 views
0

Я написал хранимую процедуру в цикле в MS SQL Server 2008 что-то вроде этогоКак получить данные из таблицы, используя цикл while?

BEGIN TRANSACTION 
WHILE(@first <= @last) 
BEGIN 

Select @LineOfAuthorityNameSubString = TempLineOfAuthority from #tbTempLineOfAuthority; 

Select @tbLineOfAuthorityId = LineOfAuthority 
from tbLineOfAuthority where LineOfAuthorityX = @LineOfAuthorityNameSubString; 

INSERT INTO tbProductLineOfAuthority(ProductId, LineOfAuthortyId) 
VALUES(@tbProductId, @tbLineOfAuthorityId); 

SET @first += @step 
END 
COMMIT TRANSACTION 

Сейчас вопрос находится в этой строке кода

Select @tbLineOfAuthorityId = LineOfAuthority 
    from tbLineOfAuthority where LineOfAuthorityX = @LineOfAuthorityNameSubString; 

Переменная @tbLineOfAuthorityId получает то же самое значение за все время цикла. Пожалуйста, помогите мне !!!

+3

Почему и использовать Loop здесь? Просто используйте один выбрать со вставкой и вот оно. – Darka

+0

Ваша треска e будет вставлять те же '@ tbProductId' и' @ tbLindeOfAuthorityId' для каждого цикла вашего цикла, является ли это предполагаемым поведением? –

+0

'@ first',' @ last' и '@ step' не используются в теле цикла, они могут только заставлять тело работать многократно. Ничто в теле цикла не будет установлено значение '@ tbLineOfAuthorityId', поэтому оно всегда будет одинаковым. – Jodrell

ответ

0

Если вы хотите получить данные из таблицы с использованием цикла, используйте CURSOR.

Я объясню более подробно в данный момент, но, сначала рассмотрит,

большинство курсора на основе подходов могут переписаны более эффективное использование наборов.

Если вы можете написать набор запросов на основе, используя SELECT и INSERT к примеру, это будет очень вероятно, будет лучшим вариантом.

Для примера основанного на наборе подхода к конкретной проблеме см. Bernd Linde's answer. Канонический ответ на ваш заявленный вопрос следует.


Если, однако нужно CURSOR, вот несколько рекомендаций,

Поскольку вы будете использовать данные в моде только для чтения и сканирования от начала до конца, вы можете сделать это явным в определении. Поскольку курсор будет READ ONLY и FORWARD_ONLY использовать аргумент FAST_FORWARD, это имеет большое значение для производительности.

Курсор будет использоваться только для этой партии, поэтому его следует объявить аргументом LOCAL.

Код должен выглядеть как этот

-- Declare the cursor. 
DECLARE [someName] CURSOR LOCAL 
     FAST FORWARD 
FOR 
    SELECT 
      [Some], 
      [Other] 
     FROM 
      [SomeTable]; 

OPEN [someName]; 
BEGIN TRY 
    -- Declare variables for storing the row. 
    DECLARE @some INT; 
    DECLARE @other NVARCHAR(MAX); 

    -- Get the first row 
    FETCH NEXT FROM [someName] INT @some, @other; 

    -- Loop through all the rows 
    WHILE @@FTECH_STATUS = 0 BEGIN 
     -- Do something useful with @some and @other 

     -- Get the next row. 
     FETCH NEXT FROM [someName] INT @some, @other; 
    END 

END TRY 
BEGIN CATCH 
    -- Error Handling 
END CATCH 

-- Always close and de-allocate the cursor, once it is opened. 
CLOSE [someName]; 
DEALLOCATE [someName]; 
+0

Я не получаю вышеуказанный код ... Можете ли вы предоставить мне пример –

1

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

Как сказано в разделе комментариев по другим, если не является обязательным требованием, почему вы используете @first, @last и @step, что вы не упомянули, весь ваш фрагмент кода может быть заменен одним оператором вставки:

insert into tbProductLineOfAuthority 
    (ProductId, 
     LineOfAuthortyId) 
select @tbProductId, 
     loa.LineOfAuthority 
    from tbLineOfAuthority loa 
     join 
     #tbTempLineOfAuthority tla on tla.TempLineOfAuthority = loa.LineOfAuthorityX 

Это заявление будет вставить все значения по мере необходимости (в соответствии с текущим вопросом и предположения, что нет никакого дополнительного смысла использования @step.

+0

+1 Я самостоятельно написал и разместил ваш ответ, а затем заметил двуличие. – Jodrell

Смежные вопросы