查询服务器未使用的过程

时间:2015-03-19 11:15:20

标签: 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.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

现在我想把两者结合起来。首先获取所有过程的列表,然后通过第二个片段中的代码运行它。最后,列出那些没有返回结果的那些(或者在技术上,那些返回一个结果的那些,因为过程的名称将始终出现在过程的定义中)。

现在我创建列表(第一个片段)并检查它是否可以在任何地方访问(第二个片段),但我是手动完成的。我该如何实现自动化?

3 个答案:

答案 0 :(得分:1)

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

你可以试试这个:

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;

答案 1 :(得分:0)

如果您只想在第二个查询中迭代第一个查询的结果,则可以创建别名并将其反馈。例如:

;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

或类似的东西。如果你想要数字,你也可以坚持第二个选择条款(因为我想这将返回很多结果)。

答案 2 :(得分:0)

要获取仅使用过程的列表,我稍微修改了 king.code 的(非常有帮助的)解决方案:

-- 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

如果过程的名称仅在过程声明中出现 - 那么数据库中没有对此过程的其他引用。