Когда процедурные запросы абсолютно необходимы?

8

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

Я понимаю разницу между ними, я просто никогда не сталкивался с ситуацией, когда мне нужно использовать курсор. Мне интересно, есть ли такие ситуации.

Томас Стрингер
источник

Ответы:

9

По своему опыту я несколько раз сталкивался с процедурными / итеративными подходами.

API позволяет работать только с одной строкой

Если бы я хотел программно изменить тип данных с реального на десятичный в таблице, содержащей 500 неправильно набранных столбцов, как задает этот вопрос SO , то курсор - это хороший подход, поскольку DDL не позволяет изменять несколько столбцов в одном выражении.

Набор на основе не масштабируется

Если у вас есть книга по SQL Server MVP Deep Dives , глава 4 «Итерация на основе множеств: третья альтернатива» Хьюго Корнелиса, есть несколько отличных вариантов использования для комбинированных операций на основе курсора / множества. Две из классических проблем, на которые ссылается автор главы, - это « Итоги работы» и « Упаковка в бин» .

Я использовал подход итерации на основе множеств с хорошим успехом для плохо разработанного процесса, который я унаследовал на последней работе. Короче говоря, был процесс, который раз в год должен был обновлять 50-75 миллионов строк, и попытка сделать это в одном наборе взорвала бы наши журналы. Разбивая обновления на более мелкие партии из N строк, это позволяло журналу продолжать работу и фактически заканчивалось быстрее, чем в предыдущем году, когда они просто выделяли метрическую тонну больше дискового пространства.

billinkc
источник
6

Когда что-то не может быть сделано на основе.

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

Одним из примеров процедурного кода будет отправка электронного письма в строке с разным содержанием в строке

Большая часть кода SQL для использования DBA носит процедурный характер. Например, цикл (CURSOR или WHILE: без разницы) для баз данных и таблиц для перестройки индексов и обновления статистики.

Некоторые конструкции SQL допускают построчную обработку в контексте набора, например CROSS APPLY, например, в SO: SELECT TOP 5 строк для каждого FK (хотя обратите внимание и на решение ROW_NUMBER ())

Редактировать: расширяя ответ @ billinkc ...

CROSS APPLY позволяет устанавливать операции на основе с пользовательскими функциями, которые имеют «однорядный API»

ГБН
источник
2

Я знаю, что вы спрашиваете о SQL Server, но в мире Oracle (в прошлом) временные таблицы стоили очень дорого, поэтому процедуры и триггеры на основе курсоров были быстрее и дешевле для сервера. В SQL Server стоимость курсоров была намного выше, чем у временных таблиц, поэтому написание кода на основе курсоров не поощрялось. Я почти уверен, что эти несоответствия были устранены в последнее десятилетие.

Чтобы справиться с этими ситуациями, у большинства людей есть общее правило, позволяющее избегать помещения бизнес-логики в базу данных. Если вы можете абсолютно всегда это делать, то не будет никаких причин для процедурной логики ни в T-SQL, ни в PL / SQL. Реляционные базы данных хороши в основанной на множестве логике. Большинство современных языков программирования хороши в процедурной логике. Лучше всего использовать каждый для того, в чем они хороши.

Некоторые триггеры аудита, с которыми я работал, имели довольно сложные правила для того, что нужно проверять и где что-то нужно обновлять / регистрировать. Некоторые были для синхронизации систем отчетности с транзакционными системами (это был не мой выбор, но они хотели этого). Некоторые были за формулярную систему. Формуляр - это список лекарств, и для каждой страховой компании, что они будут покрывать / не покрывать, и если назначено лекарство_X, какие замены покрываются страховкой. Кроме того, для разных групповых полисов в одной и той же страховой компании характерно платить за разные лекарства.

Tangurena
источник