架构更改后如何检测损坏的存储过程?
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%'
我有一个包含多达数百个 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%'