架构更改后如何检测损坏的存储过程?

How can I detect broken stored procedures after a schema change?

我有一个包含多达数百个 table 和数百个存储过程的数据库。 数据库架构已更改(e.x:某些 tables/columns 已重命名,某些列已 deleted/added 等)。

问题是:如何检测受这些更改(在执行时产生错误)影响的过程,而不实际执行它们,因为一个一个地执行它们大量的人工和耗时工作?

编辑

The closest solution I've found until now is this: sys.dm_sql_referenced_entities. A query like SELECT * FROM sys.dm_sql_referenced_entities ('dbo.procedure_name', 'OBJECT'); returns an error if procedure procedure_name is broken by those changes.

So, I can get the names of all procedures and run the upper query in a loop for each procedure name, and do some kind of logic in there, like printing the procedure name in case of error.


您可以试试这个查询,请注意,在某些情况下这也会列出误报。

查询以获取 invalid 个对象的列表:

select QuoteName(OBJECT_SCHEMA_NAME(referencing_id)) + '.' + QuoteName(OBJECT_NAME(referencing_id)) AS ProblemObject,
       o.type_desc,
       ISNULL(QuoteName(referenced_server_name) + '.', '')
         + ISNULL(QuoteName(referenced_database_name) + '.', '')
         + ISNULL(QuoteName(referenced_schema_name) + '.', '')
         + QuoteName(referenced_entity_name) AS MissingReferencedObject
from   sys.sql_expression_dependencies sed
  left join sys.objects o on sed.referencing_id=o.object_id
where  (is_ambiguous = 0)
and  (OBJECT_ID(ISNULL(QuoteName(referenced_server_name) + '.', '')
       + ISNULL(QuoteName(referenced_database_name) + '.', '')
       + ISNULL(QuoteName(referenced_schema_name) + '.', '')
       + QuoteName(referenced_entity_name)
     ) IS NULL)
order by ProblemObject, MissingReferencedObject

可以找到更多信息here

当您重新设计方案时,其他有用的查询可以是这个

查询查找被其他人调用的过程:

declare @t table (procname varchar(200), called_in varchar(200))
declare @ProcName varchar(200)

declare crProcs cursor local FAST_FORWARD READ_ONLY for
         select distinct
                o.name as procedure_name
         from   sys.sql_modules m
           inner join sys.objects o ON m.object_id = o.object_id
         where o.Type = 'P'

open crProcs
fetch next from crProcs into @ProcName
while @@FETCH_STATUS = 0
begin
     insert into @t (procname, called_in)
     select @ProcName,
            o.name
     from   sys.sql_modules m
       inner join sys.objects o ON m.object_id = o.object_id
     where  m.definition Like '%' + @ProcName + '%'
     group by o.name

     fetch next from crProcs into @ProcName
end 
close crProcs
deallocate crProcs

select * 
from   @t t
where  1 < (select count(1) from @t t2 where t2.procname = t.procname )

查询查找正在使用另一个对象的所有对象:

SELECT DISTINCT
       o.name AS Object_Name,
       o.type_desc,
       m.*
FROM   sys.sql_modules m
  INNER JOIN sys.objects o ON m.object_id = o.object_id
WHERE m.definition Like '%MyTableThatIWantToChangeTheScheme%'