Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 цикл по результатам select запроса в хранимой процедуре  [new]
r00xus
Member

Откуда:
Сообщений: 34
здравствуйте коллеги.

можно ли в хранимой процедуре в MS Sql Server использовать анонимный курсор для цикла по результатам select.

В Oracle это выглядело бы так:
BEGIN
  FOR s_line IN
  (
    SELECT * 
    FROM
      some_table
  )
  LOOP
    -- обработка
  END LOOP;
END;

В Firebird так:
for
    select
       id,
       name
    from
       some_table
    into
       :l_id,
       :l_name
do
begin
   -- обработка
end;

а все что я нашел в MS Sql Server это явное объявление курсора что очень громоздко. Есть ли что-то подобное Oracle или Firebird?
10 апр 17, 11:24    [20384248]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
r00xus,

я бы сказал, что в ms sql подход построчной обработки это исключение, а не норма.
10 апр 17, 11:28    [20384284]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
LSV
Member [заблокирован]

Откуда: Киев
Сообщений: 30817
по сабжу: можно :)
Кидаем ресултсет во времянку.
В цикле while получаем оттуда по одной записи (top 1),
обрабатываем,
удаляем эту запись, чтоб повторно не попала.
и т.д.
(профит)


но это извращение или глупая задача для собеседования. Зато анонимно и даже без курсора. бгг....
10 апр 17, 13:30    [20384801]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
LSV,

аж больно стало от такого варианта :)
10 апр 17, 13:32    [20384809]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30830
r00xus
все что я нашел в MS Sql Server это явное объявление курсора что очень громоздко.
Ну, не такое уж громоздкое :-)

Да, как уже написали, MSSQL - это РСУБД, в нём принято делать операции над множествами.
Синтаксис циклов типа оракловского, и, не дай бог, построчные триггеры, сразу приведёт к тоннам говнокода и ошибкам.
10 апр 17, 14:41    [20385225]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
энди
Member

Откуда: Киров, Россия
Сообщений: 1096
А почему собственно, вот скажем есть у меня хранимка которая делает с счетом какие-то действия по коду счета. Теперь мне надо обработать все счета, выбранные по какому-то алгоритму.
Логично сделать курсор с выбором кодов счетов и сделать вызов хранимки обрабатывающей счет по его коду.
Или я чего-то не понимаю и Вы имеете ввиду что-то другое?
10 апр 17, 15:22    [20385413]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1067
энди,
логично такую бизнес-логику вынести с сервера данных на сервер приложений
10 апр 17, 15:24    [20385422]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
энди
Member

Откуда: Киров, Россия
Сообщений: 1096
Да с чего бы это? У меня тонкий клиент в котором бизнес-логики никакой, приложение не более чем оболочка для отображения данных и не более.
10 апр 17, 15:29    [20385451]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1067
энди,
И каким боком тут тонкий клиент? Ему религия не позволяет на сервер приложений обращаться? Только сервер данных долбить разрешено?
10 апр 17, 15:33    [20385483]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
энди
Member

Откуда: Киров, Россия
Сообщений: 1096
Зачем плодить сущности без необходимост?. Вот у меня клиент писанный на Delphi XE7 + SDAC (компоненты доступа). Работаем напрямую с БД. Пользователь выполняет каку-то операцию передавая на сервер параметры запуска для некоей хранимой процедуры, запускаем цикл по выборке построенной с помощью переданных параметров и натравливаем на каждую строку выборки необходимую для обработки одной строки выборки хранимую процедуру. Вопрос, зачем мне тут сервер приложений?
Хранимая процедура прекрасно заменит мне сервер приложений. Меньше кода, проще поддержка.
10 апр 17, 15:41    [20385545]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
LSV
Member [заблокирован]

Откуда: Киев
Сообщений: 30817
энди
Зачем плодить сущности без необходимост?. Вот у меня клиент писанный на Delphi XE7 + SDAC (компоненты доступа). Работаем напрямую с БД. Пользователь выполняет каку-то операцию передавая на сервер параметры запуска для некоей хранимой процедуры, запускаем цикл по выборке построенной с помощью переданных параметров и натравливаем на каждую строку выборки необходимую для обработки одной строки выборки хранимую процедуру. Вопрос, зачем мне тут сервер приложений?
Хранимая процедура прекрасно заменит мне сервер приложений. Меньше кода, проще поддержка.
+500. СП не нужен.
10 апр 17, 15:48    [20385593]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
Dmitry V. Liseev
Member [заблокирован]

Откуда: Санкт-Петербург
Сообщений: 5490
энди
запускаем цикл по выборке
Потому, что при миллиарде записей и тысяче процессорных ядер такой цикл будет обрабатывать записи последовательно по одной на одном ядре. А железо будет простаивать. А правильный тру реляционный программист пишет запросы без циклов и курсоров. И тогда ядро СУБД сможет автоматически распараллелить запрос по процессорным ядрам и NUMA блокам.
10 апр 17, 15:49    [20385602]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
hoolygan
Member

Откуда:
Сообщений: 12
энди, смотря для чего хранимка писалась, и что должна впоследствии возвращать. Ситуации разные. Может быть был смысл писать не на курсорах, а использовать временную таблицу для списка счетов, а потом вызывать функцию на каждом значении временной таблички, в которую передавать счет, а на выходе иметь результат. И тогда безо всяких циклов/курсоров. ИМХО
10 апр 17, 15:54    [20385630]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
waszkiewicz
Member

Откуда:
Сообщений: 1067
LSV,

Мыслить построчно в РСУБД вредно
10 апр 17, 15:55    [20385641]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
LSV
Member [заблокирован]

Откуда: Киев
Сообщений: 30817
И тогда безо всяких циклов/курсоров
Речь шла об использовании больших массивов уже готового отлаженного кода (ХП). И важно, что этот код в одном месте. Если его надо поправить, то только тут. И изучать только его, а не его многочисленные клоны в куче мест большого проекта. И то если удастся эти клоны найти, что не факт.

Все это может быть гораздо важнее производительности.
10 апр 17, 16:01    [20385686]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
[quot LSV]
Все это может быть гораздо важнее производительности.
лень разработчика важнее производительности, я правильно понимаю?

и в глобальном плане ваши "массивов уже готового отлаженного кода (ХП)" надо научить/переписать для работы как с одной строкой так и с 1000 без курсоров и простите "WHILE + DELETE TOP (1) " и MS SQL <> ORACLE и в любой книге вам будет сразу написано "работайте с множествами в отличии от oracle" ну как-то так :)
10 апр 17, 16:07    [20385727]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5112
нет абсолютного зла (тригеры, курсоры ...), важен контекст.
иногда, действительно нужно построчно вызывать процедуру
ну и не стоит забывать, что производительность t-sql, скажем так, ортогональна "красоте кода", имхо.
10 апр 17, 16:09    [20385734]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
Dmitry V. Liseev
Member [заблокирован]

Откуда: Санкт-Петербург
Сообщений: 5490
LSV
Все это может быть гораздо важнее производительности.
Ну, таки надо смотреть по ситуации. У нас система от вендора, где всё на курсорах. Мы её загрузили настолько плотно, что весь этот код в критичных местах пришлось переписать. Иначе тяжело взлетало.
10 апр 17, 16:17    [20385783]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
энди
Member

Откуда: Киров, Россия
Сообщений: 1096
Я просто к тому что не надо оголтело писать курсоры зло, курсоры не зло, а вполне себе решение. Другое дело как их использовать.
Я как-то видел такое решение, как вспомню так вздрогну, система была реализована на C#, EF и SQL Server. 2 таблицы, список счетов и список записей в счетах, классический master-detail. В итоге на профайлере я наблюдаю картину от которой у меня волосы на голове начинают шевелится. Сначала идет запрос на список счетов, а затем на каждый счет клиент отправляет на сервер запрос типа select count(*) from reestr where schet_id= :schet_id и так 10 тысяч раз. Потому как счетов на клиента упало 10 тысяч :)
И ведь я не могу сказать что EF такая уж плохая вещь, важно то как ты используешь тот или иной инструмент.
10 апр 17, 22:58    [20387109]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
энди
Member

Откуда: Киров, Россия
Сообщений: 1096
А, да, забыл написать какую задачу решали с помощью подобного изврата, надо было отобразить список счетов с количеством записей в каждом :)
10 апр 17, 23:03    [20387121]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
LSV
Member [заблокирован]

Откуда: Киев
Сообщений: 30817
лень разработчика важнее производительности, я правильно понимаю?
Неправильно. Грамотный разработчик сначала все взвесит. Если массивный запрос с курсором дольше на 5%, то его можно применять, если это действительно упрощает/унифицирует код.
Самые быстрые и компактные программы - на ассемблере (теоретически конеш).
Но почти никто не пишет на асме. Потому что леняться. :)

Большинство ERP-систем используют именно построчно-навигационную обработку. Тоже ленятся. :)
11 апр 17, 09:19    [20387679]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
LSV
лень разработчика важнее производительности, я правильно понимаю?
Неправильно. Грамотный разработчик сначала все взвесит. Если массивный запрос с курсором дольше на 5%, то его можно применять, если это действительно упрощает/унифицирует код.
Самые быстрые и компактные программы - на ассемблере (теоретически конеш).
Но почти никто не пишет на асме. Потому что леняться. :)

Большинство ERP-систем используют именно построчно-навигационную обработку. Тоже ленятся. :)

ну вы для начала осознайте на что же влияет курсор, кроме вашего единственного параметра "дольше" потом обсудим.
Про ERP отдельная радость, в большинстве своём написано под унифицированные решения которые масштабируются непрогнозируемо и построчная обработка приходит как вынужденное решение ибо там закладывают моножественность решения. И да в большинстве своём когда они вырастают до размеров среднего завода-парохода, все приходят и говорят у нас это не считается за сутки...
11 апр 17, 09:25    [20387693]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
Penner
Member

Откуда:
Сообщений: 320
DECLARE @id INT
, @Name nvarchar(20)

DECLARE @cur CURSOR

SET @cur = CURSOR
FOR
SELECT	id                  
	,Name
FROM    some_table
FOR READ ONLY

FETCH NEXT
FROM @cur
INTO @ID
,@Name

WHILE @@fetch_status = 0
BEGIN
...

	FETCH NEXT
	FROM @cur
	INTO @ID
	,@Name

END

CLOSE @cur

DEALLOCATE @cur
11 апр 17, 10:18    [20387841]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30830
энди
А почему собственно, вот скажем есть у меня хранимка которая делает с счетом какие-то действия по коду счета. Теперь мне надо обработать все счета, выбранные по какому-то алгоритму.
Логично сделать курсор с выбором кодов счетов и сделать вызов хранимки обрабатывающей счет по его коду.
Или я чего-то не понимаю и Вы имеете ввиду что-то другое?
Почему нелогично сделать процедуру, которая сделает "что то" сразу с группой счетов?
Если операция возможна над множеством, зачем делать эту операцию над каждым элементом множества?
Не делайте процедуры, которые в состоянии работать только с одним элементом.
Это как бы общий подход.

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

И возможность делать "простые перечисления" будут сильно провоцировать писать криво, особенно программистов, пришедших с других языков.
11 апр 17, 18:19    [20390842]     Ответить | Цитировать Сообщить модератору
 Re: цикл по результатам select запроса в хранимой процедуре  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30830
энди
Я просто к тому что не надо оголтело писать курсоры зло, курсоры не зло, а вполне себе решение. Другое дело как их использовать.
Да, правильно.
Но я и не пишу, что это однозначное зло.

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

И тут так же. В системе хранения и обработки множеств естественно оперировать именно множествами, работая с "отдельными битами" только в специальных случаях.
11 апр 17, 18:24    [20390869]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить