Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как лучше оформить цикл для курсора?  [new]
Mr. While
Guest
Товарищи, расскажите, какой из вариантов использовать предпочтительней и почему?

fetch next from curMyCursor into @ID
while @@fetch_status != 0
begin
  -- some code
  fetch next from curMyCursor into @ID
end


while 1 = 1
begin
  fetch next from curMyCursor into @ID
  if @@fetch_status != 0
    break
  -- some code
end
1 янв 14, 11:44    [15370524]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
aleks2
Guest
Лучче - без курсора.
1 янв 14, 12:48    [15370567]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
user89
Member

Откуда:
Сообщений: 2083
Mr. While,
c Новым Годом!

Я использую примерно такую конструкцию
declare cur cursor local fast_forward read_only for
  select number, flag from #test order by number

open cur
fetch cur into @number, @flag
begin tran
while @@fetch_status = 0
begin
  ...
  fetch cur into @number, @flag
end
commit tran
close cur
deallocate cur
1 янв 14, 12:49    [15370568]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
user89
Member

Откуда:
Сообщений: 2083
конечно, while оборачивать в транзакцию необязательно, и зависит от ситуации.
1 янв 14, 12:51    [15370571]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
Mr. While
Guest
В первом примере ошибся с условием. нужно "=" вместо "!=".
Мне больше нравится 2-й вариант, где не нужно дублировать "fetch next..", коллеги же склоняются к первому, аргументируя тем, что там идет одна проверка вместо 2-х как во втором.
1 янв 14, 12:57    [15370577]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
Glory
Member

Откуда:
Сообщений: 104760
если уж так хочется без while
cycle_begin:
fetch next from curMyCursor into @ID
if @@fetch_status = 0
begin
 -- some code
 goto cycle_begin
end
1 янв 14, 13:05    [15370585]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
sdet
Member

Откуда:
Сообщений: 463
Mr. While,

Интересно для какого варианта вы используете курсор. Без него никак?
1 янв 14, 13:05    [15370586]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 5975
sdet
Без него никак?

Бывает, что никак. Например, есть системы (я знаю две таких), где для генерации id в таблице используется ХП - соответственно, при массовой вставке без курсора не обойтись (мопед системы не наши, мы их просто снабжаем своими обвесками). Я делаю как-то так:
declare
  @t table (
    id ...,
    ...
  );
insert into @t (....) select ....; -- все нужное, кроме id
declare
  cr cursor local for select id from @t ;
declare
  @id ...;
open cr;
while 1=1
begin
  fetch next from cr into @id;
  if @@fetch_status<>0 break;
  exec dbo.up_get_next_id @id out;
  update @t set id=@id where current of cr;
end;
close cr;
deallocate cr;
insert into mytable select .. from @t;
1 янв 14, 13:22    [15370614]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
Mr. While
Guest
sdet
Mr. While,

Интересно для какого варианта вы используете курсор. Без него никак?

Обычно использую их для последовательного вызова сохраненных процедур, в которые передаются параметры, взятые из курсора.
1 янв 14, 13:30    [15370626]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31442
Mr. While
какой из вариантов использовать предпочтительней и почему?
Второй, естественно - код не дублируется.
1 янв 14, 13:45    [15370643]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
user89
Member

Откуда:
Сообщений: 2083
Сон Веры Павловны,

у Вас есть хорошая тема 15281395
Там можно решить курсором? Вчера накидал черновое решение, ~ 30 сек. на 1 млн. записей.
1 янв 14, 14:30    [15370697]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
Mr. While
Guest
alexeyvg
Mr. While
какой из вариантов использовать предпочтительней и почему?
Второй, естественно - код не дублируется.


А как насчет аргумента коллег о двойном условии? Или он несостоятелен? Хотелось бы услышать побольше мнений авторитетных товарищей. Особенно интересуют мнения SomewhereSomehow, Гость333, Дэйва Пинала, Пола Рэндала и Кимберли Трипп.
1 янв 14, 20:52    [15371477]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
Mr. While
А как насчет аргумента коллег о двойном условии? Или он несостоятелен?
Если этот вопрос терзает всерьез, возьмите и сравните производительность двух вариантов цикла на ваших типичных задачах. Вряд ли вы обнаружите разницу, на которую стоит обращать внимание.
Гораздо продуктивнее будет, если позволит версия, переписать процедуры под обработку множества строк и вообще избавиться от курсоров/циклов.
1 янв 14, 21:48    [15371638]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31442
Mr. While
А как насчет аргумента коллег о двойном условии?
Коллеги, как я понял, while 1 = 1 считают "проверкой условия"?

Это во первых не факт, что сервер там что то проверяет (зависит конечно от компилятора), во вторых, затраты на это слишком малы, что бы их можно было замерить даже при пустом цикле, а при непустом тем более.

А вот лишние затраты на поддержку и понимание кода, написанного past-copy, какие то будут.
1 янв 14, 22:16    [15371681]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
o-o
Guest
Mr. While
А как насчет аргумента коллег о двойном условии? Или он несостоятелен? Хотелось бы услышать побольше мнений авторитетных товарищей. Особенно интересуют мнения SomewhereSomehow, Гость333, Дэйва Пинала, Пола Рэндала и Кимберли Трипп.


по-моему, у кого-то 1-ое апреля вместо 1-ого января.
еще можно диссертацию написать на тему: "влияние проверки 1=1 на быстродействие курсора"
-----
кстати, сам Pinal Dave про себя говорит: "пИнал давЕ".
но лучше, конечно, не мелочиться, а написать последним двоим из списка авторитетов.
а то им скучно, а тут вдруг такая идея, что еще поисследовать
1 янв 14, 22:28    [15371699]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
Mr. While
Guest
alexeyvg
Mr. While
А как насчет аргумента коллег о двойном условии?
Коллеги, как я понял, while 1 = 1 считают "проверкой условия"?

Это во первых не факт, что сервер там что то проверяет (зависит конечно от компилятора), во вторых, затраты на это слишком малы, что бы их можно было замерить даже при пустом цикле, а при непустом тем более.

А вот лишние затраты на поддержку и понимание кода, написанного past-copy, какие то будут.


Да, я тоже считаю, что потери от проверки 1 = 1 должны быть несущественны, если они вообще имеются.
Со стороны коллег был ещё один довод в пользу первого варианта. Это то, что использование бесконечного цикла - дурной тон (видимо, дублирование кода под "дурной тон" у них не попадает). Но, в данном случае, я считаю, что применение бесконечного цикла оправдано. Единственное, что меня настораживает, это то, что в MSDN пользуются первым вариантом. Может все-таки есть какой "подводный камень" во втором варианте с while 1 = 1?
1 янв 14, 22:44    [15371720]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31442
Mr. While
Со стороны коллег был ещё один довод в пользу первого варианта. Это то, что использование бесконечного цикла - дурной тон (видимо, дублирование кода под "дурной тон" у них не попадает)
Дурной тон то, что в T-SQL нету оператора цикла без условий, и циклов с пост-проверкой, как в других языках.

Уж дублирование строки fetch next (а она может быть не такая короткая, допустим, может быть несколько десятков переменных) по любому хуже while 1=1
Mr. While
Может все-таки есть какой "подводный камень" во втором варианте с while 1 = 1?
Да откуда...

Нужно только писать аккуратно, fetch next и проверку @@fetch_status делать в самом начале, не разбрызгивать по коду.
1 янв 14, 23:03    [15371747]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
sdet
Member

Откуда:
Сообщений: 463
Mr. While
sdet
Mr. While,

Интересно для какого варианта вы используете курсор. Без него никак?

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

А перестроить хранимые процедуры на table valued функции для использования с cross apply есть возможность?
2 янв 14, 01:12    [15371964]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
Mr. While
Guest
sdet
Mr. While
пропущено...

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

А перестроить хранимые процедуры на table valued функции для использования с cross apply есть возможность?


Суть темы не в том, как избавиться от курсора, а в том, какой из методов его оформления более логичный, правильный, удобный (нужное подчеркнуть).
П.С.: Процедуры, вызываемые в цикле курсора занимаются модификацией таблиц и не ограничиваются простыми update, insert или delete.
2 янв 14, 02:05    [15372054]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
Glory
Member

Откуда:
Сообщений: 104760
Mr. While
а в том, какой из методов его оформления более логичный, правильный, удобный (нужное подчеркнуть).

Это все будут субъективные оценки. В каждом из подходов будут свои +/-.
И лучше всего будет выглядеть код с подробными комментариями.
2 янв 14, 11:20    [15372264]     Ответить | Цитировать Сообщить модератору
 Re: Как лучше оформить цикл для курсора?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
-- close cur
deallocate cur
close нужен только если вы хотите воспользоваться курсором повторно.
два fetch - можно нарваться на то что забыли синхронизировать.

Если в системе есть необходимость курсора - уже не важно как он написан, это как пытаться не пукнуть после того как провалился в нужник, по самые уши.
2 янв 14, 22:03    [15373272]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить