Sql server 查询服务器中未使用的过程

Sql server 查询服务器中未使用的过程,sql-server,tsql,Sql Server,Tsql,我想写一个查询来查找数据库中所有未使用的过程 我有一段代码列出了数据库中的所有过程: SELECT p.name AS 'SP Name' FROM sys.procedures AS p WHERE p.is_ms_shipped = 0 ORDER BY p.name 我还有另一段代码,用于检查表达式是否在现有过程中的任何位置使用: declare @expression nvarchar(100) = '%sp_myProcedure%' SELECT DISTINCT o.

我想写一个查询来查找数据库中所有未使用的过程

我有一段代码列出了数据库中的所有过程:

SELECT p.name AS 'SP Name'
FROM sys.procedures AS p
WHERE p.is_ms_shipped = 0
ORDER BY p.name
我还有另一段代码,用于检查表达式是否在现有过程中的任何位置使用:

declare @expression nvarchar(100) = '%sp_myProcedure%'

SELECT DISTINCT 
    o.name AS Object_Name,
    o.type_desc
FROM sys.sql_modules m 
    INNER JOIN sys.objects o 
    ON m.object_id=o.object_id
WHERE m.definition Like @expression
现在我想把两者结合起来。首先获取所有过程的列表,然后在第二个代码段中运行它。最后,列出那些没有返回结果的,或者从技术上讲,那些返回一个结果的,因为过程的名称总是出现在过程的定义中

现在,我创建第一个代码段列表,并检查是否在第二个代码段的任何地方访问了它,但我是手动执行的。如何实现自动化?

您可以使用交叉应用。APPLY运算符允许您为查询的外部表表达式返回的每一行调用表值函数

您可以尝试以下方法:

SELECT P.name AS 'SP Name'
             ,TU.Object_Name
FROM sys.procedures AS P
CROSS APPLY (SELECT DISTINCT O.name AS Object_Name
                            ,O.type_desc
             FROM sys.sql_modules AS M
             INNER JOIN sys.objects AS O
                ON M.object_id = O.object_id
             WHERE M.definition LIKE '%' + P.name + '%') AS TU
WHERE P.is_ms_shipped = 0
ORDER BY P.name;

如果只想在第二个查询上迭代第一个查询的结果,可以创建一个别名并将其传递给其他查询。例如:

;with prc_names as (SELECT p.name AS sp_name
FROM sys.procedures AS p
WHERE p.is_ms_shipped = 0)

SELECT  
p.sp_name as 'SP Name',
o.name AS Object_Name,
o.type_desc
FROM sys.sql_modules m, prc_names p 
INNER JOIN sys.objects o 
ON m.object_id=o.object_id
WHERE m.definition Like p.sp_name
group by p.sp_name, o.name, o.type_desc
order by p.sp_name

或者类似的东西。如果您需要数字,也可以在第二个select子句上添加一个计数,因为我认为这将返回大量结果。

要获得仅未使用的过程的列表,我稍微修改了king。代码提供了非常有用的解决方案:

-- List only unused procedures
SELECT v.SP_Name FROM 
    (SELECT P.name AS SP_Name ,TU.Object_Name
    FROM sys.procedures AS P
    CROSS APPLY (SELECT DISTINCT O.name AS Object_Name
                                ,O.type_desc
                 FROM sys.sql_modules AS M
                 INNER JOIN sys.objects AS O
                     ON M.object_id = O.object_id
                 WHERE M.definition LIKE '%' + P.name + '%') AS TU
    WHERE P.is_ms_shipped = 0) v
GROUP BY v.SP_Name 
HAVING COUNT(v.SP_Name) <= 1
如果过程的名称出现一次,则它仅出现在过程声明中,因此数据库中没有对该过程的其他引用