Как использовать рекурсивную функцию для обновления таблицы? - PullRequest
0 голосов
/ 27 сентября 2010

Это продолжение от этого вопроса .

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

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

Я подумываю попытаться сделать это:

  • Создать рекурсивную функцию, чтобы онатаблица в качестве параметра
  • Если таблица пуста, создайте ее;иначе скопируйте таблицу в новую переменную (потому что она будет доступна только для чтения)
  • обновите скопированную таблицу в функции перед выполнением рекурсивного вызова и передайте копию функции
  • вend, вернуть полную таблицу (не знаю, как я узнаю, завершена ли она еще)
  • вызвать эту функцию из хранимой процедуры, которая использует возвращенную таблицу для нескольких обновлений

Я ищу альтернативы, прежде чем я попробую что-то подобное.Кажется, это было сделано раньше.

1 Ответ

6 голосов
/ 27 сентября 2010

Любая рекурсивная реализация T-SQL рано или поздно попадет в @@NESTLEVEL cap :

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

Но из CS101 мы знаем, что любой рекурсивный алгоритм может быть реализован как итерационный алгоритм с помощью стека. Таким образом, вам нужна таблица, чтобы действовать как стек (см. Использование таблиц в качестве очередей для некоторых связанных обсуждений). Используйте хранимую процедуру, а не функцию, поскольку в T-SQL «функции» являются чем-то особенным (в основном это путь доступа к данным) и не имеют права изменять данные. Всякий раз, когда вы думаете «функция» (как в функции или методе C / C ++ / C #), вам действительно нужна хранимая процедура. Вы не можете возвращать «таблицы» из процедур, поэтому вывод должен быть таблицей, в которую вы записываете результаты.

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

...