Я понимаю ваш вопрос как «когда я изменяю схему, я хочу проверить все процедуры, которые они все еще выполняют правильно с новой схемой». То есть. если вы отбрасываете столбец, на который ссылается SELECT в процедуре, то вы хотите, чтобы он был помечен, поскольку он требует изменений. Поэтому, в частности, я не понимаю ваш вопрос как «Я хочу, чтобы процедура перекомпилировалась при следующем выполнении», так как это задание выполняется для вас механизмом, который обнаружит изменение версии метаданных, связанное с любым изменением схемы, и отбросит существующую кэшированные планы выполнения.
Мое первое наблюдение состоит в том, что то, что вы описываете в своем вопросе, обычно является работой TEST , и вы должны иметь шаг QA в процессе развертывания, который проверяет новую «сборку». Лучшее решение, которое вы могли бы иметь, - реализовать минимальный набор модульных тестов, который, по крайней мере, повторяет все ваши хранимые процедуры и проверяет выполнение каждой на корректность в тестовом развертывании. Это в значительной степени устранит все сюрпризы, по крайней мере, устранит их там, где это больно (на производстве или на площадке заказчика).
Ваш следующий лучший вариант - использовать инструменты разработки для отслеживания этих зависимостей. Visual Studio Database 2008 Database Edition предоставляет такие функциональные возможности "из коробки" и позаботится о проверке любых изменений, внесенных в схему.
И, наконец, ваш последний вариант - сделать нечто похожее на то, что предложил KM: автоматизировать итерацию всех ваших процедур в зависимости от измененного объекта (и всех процедур в зависимости от зависимых и т. Д. И т. Д. И т. Д. Рекурсивно). Недостаточно отметить процедуры для перекомпиляции, вам действительно нужно запустить ALTER PROCEDURE, чтобы запустить синтаксический анализ его текста и проверку схемы (в T-SQL все немного отличается от вашего обычного языка). цикл компиляции / выполнения, «компиляция» как таковая происходит только тогда, когда процедура фактически выполняется). Вы можете начать с итерации по sys.sql_dependencies
, чтобы найти все зависимости вашего измененного объекта, а также найти «определение модуля» зависимостей из sys.sql_modules
:
with cte_dep as (
select object_id
from sys.sql_dependencies
where referenced_major_id = object_id('<your altered object name>')
union all
select d.object_id
from sys.sql_dependencies d
join cte_dep r on d.referenced_major_id = r.object_id
)
, cte_distinct as (
select distinct object_id
from cte_dep)
select object_name(c.object_id)
, c.object_id
, m.definition
from cte_distinct c
join sys.sql_modules m on c.object_id = m.object_id
Затем вы можете запустить зависимые «модули» и воссоздать их (т. Е. Удалить их и запустить код в «определении»). Обратите внимание, что «модуль» является более общим, чем хранимая процедура, и охватывает также представления, триггеры, функции, правила, значения по умолчанию и фильтры репликации. Зашифрованные «модули» не будут иметь определения доступного определения, и чтобы быть абсолютно корректным, вы также должны учитывать различные настройки, зафиксированные в sys.sql_modules
(ANSI NULL, привязка схемы, выполнить как пункты и т. Д.).
Если вы используете динамический SQL, это невозможно проверить. Он не будет захвачен sys.sql_dependencies
и не будет проверен путем «воссоздания» модуля.
В целом, я думаю, что лучшим вариантом, с большим отрывом, является реализация проверки модульных тестов.