Найти синтаксически совпадающие хранимые процедуры в SQL Server - PullRequest
1 голос
/ 16 сентября 2011

Я гуглил вокруг, но не мог найти ничего, что могло бы мне помочь. Мы используем SQL-Server 2008 R2, и наша политика заключается в использовании хранимых процедур для всех вызовов нашей базы данных. Это работает нормально, но проблема в том, что наш список процедур вырос до более чем 600, мы делаем дубликаты синтаксически совпадающих запросов, которые написал кто-то другой (а иногда и мы).

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

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

Ответы [ 3 ]

2 голосов
/ 16 сентября 2011

Это может привести к некоторым ошибкам, если планы для хранимых процедур находятся в кеше.(Объяснение query_hash и query_plan_hash здесь )

WITH qs AS
(
SELECT *, 
       COUNT(*) OVER (PARTITION BY query_hash) qh,
       COUNT(*) OVER (PARTITION BY query_plan_hash) qph
FROM sys.dm_exec_query_stats 
)
SELECT 
       db_name(dbid) as database_name,
       object_name(objectid,dbid) as object_name,
       text,
         SUBSTRING(st.text, ( qs.statement_start_offset / 2 ) + 1, (
              ( CASE qs.statement_end_offset
              WHEN -1 THEN DATALENGTH(st.text)
              ELSE qs.statement_end_offset END -
       qs.statement_start_offset ) / 2 ) + 1) AS statement_text,
                query_hash,
       query_plan_hash 
FROM qs
CROSS APPLY  sys.dm_exec_sql_text (qs.sql_handle) st
WHERE qh>1 OR qph>1
ORDER BY qh, qph
2 голосов
/ 16 сентября 2011

Использование (и обеспечение соблюдения!) Согласованных стандартов имен должно иметь большое значение для предотвращения дублирования. Всегда используйте один и тот же стиль (я предпочитаю entity_action, например, Customer_Update). Если все ваши объекты имеют одинаковые имена, создать дубликат становится довольно сложно, если вы полностью не игнорируете стандарт.

Я понимаю, что это вам сейчас не поможет - я не знаю, как это определить, если вы не выполните грубую форсировку или не попытаетесь сопоставить планы запросов в sys.dm_exec_cached_plans, чтобы увидеть, ссылаются ли похожие / идентичные планы на разные предметы. Ничто из этого не является тривиальным.

1 голос
/ 16 сентября 2011

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

Как говорит Аарон Бертран, соглашения об именах имеют большое значение, но если вы не выполнили какое-то конкретное соглашение, это не решит вашу проблему.

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

Итак, если вы ищете процесс, который влияет на таблицы a, b и c, запуск sp_depends с a, b и c и просмотр того, какие из них активируются для всех 3, по крайней мере скажут вам, какой из 600 процедур вам нужен. читать.

sp_depends не сообщает о процессах, использующих динамический sql.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...