Как можно вызвать хранимую процедуру для каждой строки в таблице, где столбцы строки являются входными параметрами для sp без использования курсора?
sql
sql-server
stored-procedures
cursor
Йоханнес Рудольф
источник
источник
Ответы:
Вообще говоря, я всегда ищу подход, основанный на множестве (иногда за счет изменения схемы).
Тем не менее, этот фрагмент имеет свое место ..
источник
Вы можете сделать что-то вроде этого: упорядочить свою таблицу, например, по CustomerID (используя
Sales.Customer
пример таблицы AdventureWorks ), и перебрать тех клиентов, используя цикл WHILE:Это должно работать с любой таблицей до тех пор, пока вы можете определить какой-то тип
ORDER BY
столбца.источник
Итак, я бы никогда не внедрил такой код в производство, но он действительно отвечает вашим требованиям.
источник
Хороший ответ Марка (я бы прокомментировал это, если бы смог разобраться, как это сделать!)
Просто подумал, что могу указать, что может быть лучше изменить цикл, чтобы
SELECT
единственное существовало один раз (в реальном случае, когда мне нужно было сделать этоSELECT
было довольно сложно, и писать его дважды было рискованным вопросом обслуживания).источник
Если вы можете превратить хранимую процедуру в функцию, которая возвращает таблицу, вы можете использовать перекрестное применение.
Например, если у вас есть таблица клиентов, и вы хотите вычислить сумму их заказов, вы бы создали функцию, которая бы принимала идентификатор клиента и возвращала сумму.
И вы могли бы сделать это:
Где функция будет выглядеть так:
Очевидно, что приведенный выше пример может быть выполнен без определяемой пользователем функции в одном запросе.
Недостаток заключается в том, что функции очень ограничены - многие функции хранимой процедуры недоступны в пользовательской функции, и преобразование хранимой процедуры в функцию не всегда работает.
источник
Я бы использовал принятый ответ, но другая возможность состоит в том, чтобы использовать переменную таблицы для хранения пронумерованного набора значений (в данном случае это просто поле идентификатора таблицы) и перебирать их по номеру строки с помощью JOIN для таблицы, чтобы получить все, что вам нужно для действия в цикле.
источник
Начиная с SQL Server 2005, вы можете сделать это с помощью CROSS APPLY и табличной функции.
Просто для ясности, я имею в виду те случаи, когда хранимая процедура может быть преобразована в табличную функцию.
источник
Это вариант решения n3rds выше. Сортировка с использованием ORDER BY не требуется, поскольку используется MIN ().
Помните, что CustomerID (или любой другой числовой столбец, который вы используете для прогресса) должен иметь уникальное ограничение. Кроме того, чтобы сделать его максимально быстрым, необходимо включить индекс CustomerID.
Я использую этот подход на некоторых varchars, которые мне нужно просмотреть, поместив их во временную таблицу, чтобы дать им ID.
источник
Если вам не нужно использовать курсор, я думаю, вам придется делать это извне (получить таблицу, а затем выполнить для каждого оператора и каждый раз вызывать sp). Это то же самое, что использовать курсор, но только снаружи. SQL. Почему вы не используете курсор?
источник
Это вариант уже предоставленных ответов, но он должен быть более эффективным, поскольку не требует ORDER BY, COUNT или MIN / MAX. Единственный недостаток этого подхода заключается в том, что вам необходимо создать временную таблицу для хранения всех идентификаторов (предполагается, что в вашем списке идентификаторов клиентов есть пробелы).
Тем не менее, я согласен с @Mark Powell, хотя, вообще говоря, подход, основанный на множестве, все же должен быть лучше.
источник
Я обычно делаю это так, когда довольно много строк:
(На больших наборах данных я бы использовал одно из упомянутых выше решений).
источник
РАЗДЕЛИТЕЛЬ //
источник
Лучшим решением для этого является
Это был чистый текстовый формат. Хотя, если вы запускаете SP для каждой строки, вы получаете отдельный результат запроса для каждой итерации, что уродливо.
источник
Если порядок важен
источник
У меня был некоторый производственный код, который мог обрабатывать только 20 сотрудников одновременно, ниже представлена структура кода. Я просто скопировал производственный код и удалил материал ниже.
источник
Мне нравится делать что-то похожее на это (хотя это все еще очень похоже на использование курсора)
[код]
[/код]
Обратите внимание, что вам не нужен идентификатор или столбец isIterated в таблице временных / переменных, я просто предпочитаю делать это таким образом, чтобы мне не нужно было удалять верхнюю запись из коллекции, когда я выполняю цикл.
источник