如何识别引用特定表的所有存储过程


136

我在开发环境上创建了一个表用于测试目的,很少有sp引用此表。现在,我必须删除该表,并标识所有引用此表的sp。我很难找到所有sp的列表。请通过假设表名称为'x'并且数据库为sql server 2005来建议一些查询。




1
给专家:非MS SQL服务器怎么样?
Deian 2015年

Answers:


259
SELECT Name
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%TableNameOrWhatever%'

顺便说一句-这是有关此类问题的便捷资源:查询SQL Server系统目录常见问题


3
是否有理由通过访问ROUTINE_DEFINITIONon 来执行此操作INFORMATION_SCHEMA.ROUTINES
Marie

1
@Marie-SQL-Server 2005(AFAIK)没有。
Chains

2
问题,当字符串内部引用引用的对象时,此解决方案是否找到引用的对象?就像,set @Query = “SELECT * FROM Object_I_Need_To_Find_References…”;
Jeff.Clark '16

1
@ Jeff.Clark-有一种简单的方法可以找到:-)-但是,是的,它直接搜索过程文本,因此可以找到它。
Chains

2
是的:)我要花点时间来设置测试,而我只是想寻找一个懒惰/简单的答案:)
Jeff.Clark

27

以下适用于SQL2008及更高版本。提供存储过程和功能的列表。

select distinct [Table Name] = o.Name, [Found In] = sp.Name, sp.type_desc
  from sys.objects o inner join sys.sql_expression_dependencies  sd on o.object_id = sd.referenced_id
                inner join sys.objects sp on sd.referencing_id = sp.object_id
                    and sp.type in ('P', 'FN')
  where o.name = 'YourTableName'
  order by sp.Name

1
OP需要SQL-Server-2005的答案
Chains 2013年

19

有时上述查询不会给出正确的结果,内置的存储过程可用于获取表依赖关系,如下所示:

EXEC sp_depends @objname = N'TableName';

1
对我来说,这显示了触发器和视图,但没有存储过程。
NealWalters

1
注意:我在可以访问表但不能访问存储过程的系统上运行此程序,因此存储过程当然不会显示在结果中。
NealWalters

18

一种非查询方式是使用Sql Server Management Studio。

找到表,右键单击并选择“查看依赖项”。

编辑

但是,正如评论员所说,它不是很可靠。


4
在2005年,如果未按正确的顺序创建对象,则依赖项信息不可靠。
马丁·史密斯

3
正如@Martin Smith指出的那样,将创建一个引用不存在的对象的存储过程,尽管有警告,但不会在sysdepends中放置任何条目。同样,对于引用外部数据库中的表的存储过程也是如此:在任何一个数据库的sysdepends中都没有条目。另一个功能是删除/重新创建表或视图会破坏依赖关系链。这些...错误...的功能使SQL Server的依赖跟踪几乎没有用。
Nicholas Carey

7

以下查询将获取所有存储过程名称以及这些SP的相应定义

select 
   so.name, 
   text 
from 
   sysobjects so, 
   syscomments sc 
where 
   so.id = sc.id 
   and UPPER(text) like '%<TABLE NAME>%'

5
SELECT
    o.name
FROM
    sys.sql_modules sm
INNER JOIN sys.objects o ON
    o.object_id = sm.object_id
WHERE
    sm.definition LIKE '%<table name>%'

请记住,这还会在表名位于注释中或表名是正在使用的另一个表名的子字符串的情况下打开SP。例如,如果您有名为“ test”和“ test_2”的表,并且尝试使用“ test”搜索SP,则将同时获得这两个结果。


2
syscomments对于较长的过程,以这种方式进行查询是不可靠的,因为它将定义分为多行4000个字符的块。sys.sql_modules避免这种情况。
马丁·史密斯,

1
好点子。我已经更新它以sys.sql_modules代替使用。
汤姆H

3
syscomments中已被揭穿,我打的每一位左右回答同样的问题stackoverflow.com/...
GBN

5

以下查询仅在搜索表而不是列的依赖项时有效:

EXEC sp_depends @objname = N'TableName';

但是,如果您要搜索各种依赖项,则以下查询是最佳选择,它不会丢失任何内容。实际上,它提供了比所需更多的信息。

 select distinct
        so.name
        --, text 
  from 
       sysobjects so, 
       syscomments sc 
  where 
     so.id = sc.id 
     and lower(text) like '%organizationtypeid%'
  order by so.name

1
对我而言,在针对SQL Server 12.0上的数据库运行的SSMS 2014上未返回任何内容)
NealWalters

3
SELECT DISTINCT OBJECT_NAME(OBJECT_ID),
object_definition(OBJECT_ID)
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%' + 'table_name' + '%'

GO

如果必须提及表名,这将起作用。


3

在Management Studio中,您可以右键单击表格,然后单击“查看依赖项” 在此处输入图片说明

那么您会看到与表具有依赖关系的对象列表:在此处输入图片说明


1

您基本上有2个选择:

- - 选项1

SELECT DISTINCT so.name
FROM syscomments sc
INNER JOIN sysobjects so ON sc.id=so.id
WHERE sc.TEXT LIKE '%tablename%'

----选项2

SELECT DISTINCT o.name, o.xtype
FROM syscomments c
INNER JOIN sysobjects o ON c.id=o.id
WHERE c.TEXT LIKE '%tablename%'

这两个查询将为您提供所有引用所需表的存储过程。该查询依赖于2个sys表,即sysobjects和syscomments。sysobjects是存储所有DB对象名称的位置,其中包括存储过程。

syscomments包含所有过程的文本。

如果您查询: SELECT * FROM syscomments

您将拥有一个包含ID的表,该ID是到sysobjects表的映射,其中存储过程中包含的文本作为最后一列。


0

试试这个

   SELECT DISTINCT so.name
    FROM syscomments sc
    INNER JOIN sysobjects so ON sc.id=so.id
    WHERE sc.TEXT LIKE '%your table name%'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.