Перекомпилировать сохраненные процы? - PullRequest
2 голосов
/ 30 июня 2009

Есть ли способ перекомпилировать или хотя бы «проверить компиляцию» хранимых процедур в массовом порядке? Иногда мы вносим изменения в схему - добавляем или удаляем столбец и т. Д. И делаем все возможное, чтобы идентифицировать затронутые процессы только для того, чтобы быть укушенным тем, кого мы пропустили, и что будет неприятно при следующем запуске. SQLServer 2k5 или 2k8.

Ответы [ 5 ]

5 голосов
/ 30 июня 2009

Я понимаю ваш вопрос как «когда я изменяю схему, я хочу проверить все процедуры, которые они все еще выполняют правильно с новой схемой». То есть. если вы отбрасываете столбец, на который ссылается 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 и не будет проверен путем «воссоздания» модуля.

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

4 голосов
/ 30 июня 2009

Если у вас возникли проблемы с изменением таблицы и нарушением хранимых процедур, попробуйте sp_depends :

sp_depends [ @objname = ] '<object>' 

<object> ::=
{
    [ database_name. [ schema_name ] . | schema_name.
        object_name
}

и идентифицируйте их, прежде чем они сломаются. Используйте это так:

EXECUTE sp_depends  YourChangedTableName

Также вы можете использовать sp_recompile :

EXEC sp_recompile YourChangedTable

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

Вы можете использовать Management Studio или систему управления исходным кодом, чтобы сгенерировать объединенный сценарий создания всех процедур в один файл и затем запустить его.

3 голосов
/ 26 августа 2009

Я знаю, что вы имеете в виду, и во многих сценариях признает вашу потребность. Возможно, вы посмотрите на sp_refreshsqlmodule .

Удачи, Рон

1 голос
/ 30 июня 2009

Вы можете использовать DBCC FREEPROCCACHE

http://msdn.microsoft.com/en-us/library/ms174283.aspx

1 голос
/ 30 июня 2009

Просто переберите их, получив список из sysobjects, и запустите sp_recompile:

Вот ссылка, показывающая пример скрипта:
http://database.ittoolbox.com/groups/technical-functional/sql-server-l/recompile-all-stored-procedures-2764478

...