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

11

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

Проверить одну хранимую процедуру легко (я просто повторно запускаю скрипт alter и вижу, успешна ли операция), но делать это на более чем 100 процедурах немного громоздко.

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

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

Я использую SQLServer 2008 R2, и мои сценарии базы данных хранятся в проекте базы данных VS 2008.


Чтобы уточнить, я не защищаю, следует полагаться исключительно на этот подход для тестирования кода. Точно так же, как в c #, вы мгновенно обнаруживаете синтаксическую ошибку в других зависимых файлах при кодировании (а затем используете другие стратегии для тестирования, такие как модульные тесты, которые обычно на несколько порядков медленнее), я думаю, что имеет смысл обнаруживать зависимости SQL ошибки в секундах, а не запуск полного функционального теста, который обычно может занять несколько часов.

Бранн
источник

Ответы:

7

Как насчет того, чтобы запустить свой тестовый модуль, функциональные тесты, тесты интеграции и производительности? Если у вас нет никаких тестов, тогда самое время начать рассматривать схему базы данных как код и рассматривать ее как таковую, включая контроль версий и тестирование. У Алексея Кузнецова есть целая книга, посвященная этой теме: Защитное программирование баз данных на SQL Server .

Ремус Русану
источник
Тесты не всегда покрывают 100% кода, и когда они выполняются, они обычно занимают несколько часов. В c # я могу определить, компилируется ли мой код за считанные секунды (независимо от его правильности). Это не значит, что я должен загружать код (независимо от того, является ли код c # или PLSQL) в производство без надлежащего его тестирования, но не кажется разумным иметь способ быстрого обнаружения нарушенных зависимостей, не так ли?
Бранн
2
К сожалению, в настоящее время состояние SQL Server по сравнению с обнаружением зависимостей в хранимых процедурах «глубоко нарушено», см. « Понимание зависимостей SQL» или « Поддержание актуальности системного уровня в SQL Server 2008» . Есть даже сторонние инструменты, пытающиеся решить проблему
Remus Rusanu
2
Это делает модульные / функциональные тесты практически единственным надежным способом обнаружения критических изменений.
Ремус Русану
1
Для быстрой проверки проектов базы данных Visual Studio достаточно прилично справляется с проверкой любых изменений.
Ремус Русану
4

Это обходной путь, но вы можете сгенерировать сценарии CREATE PROCEDURE для базы данных (щелкните правой кнопкой мыши базу данных -> задачи -> создать сценарии), найти и заменить CREATE PROCEDURE на ALTER PROCEDURE, а затем проанализировать.

Я надеюсь, что вы получите лучший ответ здесь - мне тоже интересно! :)

JHFB
источник
Я не отмечаю ваш ответ как принятый, потому что я все еще надеюсь на более чистое решение (надеюсь, сценарий), но вы определенно получите мой +1! Спасибо.
Бранн
3
Этот подход не даст вам знать, если вы ссылаетесь на несуществующую таблицу .
Ник Чаммас
Этот подход также не сработает, если сгенерированный скрипт имеет длину более 30 тыс. Строк. Ненавижу, что знаю это ..
Эонасдан
3

Вы можете использовать Sql Server Data Tools (SSDT). Microsoft Visual Studio позволяет создавать проект Sql Server. Затем импортируют базу данных в проект и затем строят проект. Если есть какие-либо поврежденные хранимые процедуры или объекты, вы получите ошибку компиляции.

VenVig
источник
Я добавлю, что вы можете легко сгенерировать новый сценарий создания базы данных из проекта SSDT и запустить его в тестовой среде, что будет довольно тщательным подтверждением того, что нет изменений в procs / triggers / etc из-за изменений схемы.
AaronLS
3

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

Чтобы построить сценарий, опубликованный Alaa Awad ... здесь должны быть показаны схема и база данных объектов, на которые имеются ссылки. Если вы используете много временных таблиц через псевдонимы (которые иногда отображаются при использовании sys.sql_expression_dependencies), параметры UDTT или другие динамические функции, вам может понадобиться использовать функции sys.dm_sql_referenced_entitiesили sys.dm_sql_referencing_entitiesвместо них / также.

SELECT
    DB_NAME() + '.' + OBJECT_SCHEMA_NAME(sed.referencing_id) + '.' + OBJECT_NAME(sed.referencing_id) AS [referencingObject],
    isnull(sed.referenced_server_name + '.', '') + isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies sed
WHERE 
    sed.is_ambiguous = 0
    AND OBJECT_ID(isnull(sed.referenced_database_name + '.', DB_NAME() + '.') + isnull(sed.referenced_schema_name + '.', OBJECT_SCHEMA_NAME(sed.referencing_id) + '.') + sed.referenced_entity_name) IS NULL
ORDER BY
    [referencingObject], [missingReference]
Arkaine55
источник
1
Следует добавить их к предложению where: / * Не существующий тип пользователя / AND sed.referenced_entity_name NOT IN (SELECT [имя] FROM sys.types) / Не псевдоним * / AND sed.referenced_schema_name НЕ
НУЛЬ
1

используйте sys.sql_expression_dependencies, добавленные в sql server 2008

CREATE PROCEDURE [dbo].[spMaintenance_Find_Broken_Dependencies]

AS
SELECT
    OBJECT_NAME(referencing_id) AS [referencingObject],
    referenced_entity_name AS [missingReference]
FROM 
    sys.sql_expression_dependencies
WHERE 
    is_ambiguous = 0
    AND OBJECT_ID(referenced_entity_name) IS NULL
ORDER BY 
    OBJECT_NAME(referencing_id), referenced_entity_name

GO
Алаа Авад
источник
Это может быть полезно, однако это не так просто, поскольку схему также необходимо учитывать. У меня также возникают проблемы, когда sys.sql_expession_dependencies отображает используемый псевдоним, а не фактическую зависимую таблицу, которая, очевидно, не проходит тест object_id (). Наконец, он вызывает пользовательские таблицы, передаваемые в качестве параметров хранимым процедурам, что не очень полезно.
Таблу Quijico