【问题标题】:Find all stored procedures that reference a specific column in some table查找引用某个表中特定列的所有存储过程
【发布时间】:2013-11-01 14:40:57
【问题描述】:

我的表中有一个值被意外更改。有问题的列是CreatedDate:这是在创建我的项目时设置的,但它正在被存储过程更改。

我可以编写某种类型的SELECT 语句来从我的表中获取引用此列的所有过程名称吗?

【问题讨论】:

标签: sql sql-server select find columnname


【解决方案1】:

您可以使用information_schema中包含的系统视图在表格中搜索视图和(未加密)存储过程与一个脚本。我前段时间开发了这样一个脚本,因为我需要在数据库中到处搜索字段名称。

下面的脚本首先列出了包含您要搜索的列名的表/视图,然后是找到该列的存储过程源代码。它将结果显示在一个表中以区分 “BASE TABLE”、“VIEW”和“PROCEDURE”,并(可选)在第二个表中显示源代码:

DECLARE @SearchFor nvarchar(max)='%CustomerID%' -- search for this string
DECLARE @SearchSP bit = 1 -- 1=search in SPs as well
DECLARE @DisplaySPSource bit = 1 -- 1=display SP source code

-- tables
if (@SearchSP=1) begin  
  (
  select '['+c.table_Schema+'].['+c.table_Name+'].['+c.column_name+']' [schema_object], 
            t.table_type 
  from information_schema.columns c
  left join information_schema.Tables t on c.table_name=t.table_name
  where column_name like @SearchFor 
  union
  select '['+routine_Schema+'].['+routine_Name+']' [schema_object], 
         'PROCEDURE' as table_type from information_schema.routines
  where routine_definition like @SearchFor
        and routine_type='procedure'
  )
  order by table_type, schema_object
end else begin
  select '['+c.table_Schema+'].['+c.table_Name+'].['+c.column_name+']' [schema_object], 
         t.table_type 
  from information_schema.columns c
  left join information_schema.Tables t on c.table_name=t.table_name
  where column_name like @SearchFor 
  order by c.table_Name, c.column_name
end     
-- stored procedure (source listing)
if (@SearchSP=1) begin      
    if (@DisplaySPSource=1) begin
      select '['+routine_Schema+'].['+routine_Name+']' [schema.sp], routine_definition 
      from information_schema.routines
      where routine_definition like @SearchFor
      and routine_type='procedure'
      order by routine_name
    end
end

如果您运行查询,请使用“result as text”选项 - 然后您可以使用“find”在结果集中查找搜索文本(对于长源代码很有用)。

注意,如果您只想显示 SP 名称,并且如果您只是在查找表/视图而不是 SP,您可以将 @DisplaySPSource 设置为 0可以将@SearchSP设置为0

示例结果(在 Northwind 数据库中查找 CustomerID,结果通过 LinqPad 显示):

注意我已经用测试视图验证了这个脚本dbo.TestOrders 即使SELECT 语句中使用了c.*,它在此视图中也找到了CustomerID(引用表Customers 包含CustomerID,因此视图显示此列)。


注意 LinqPad用户:在C#中,你可以使用dc.ExecuteQueryDynamic(sqlQueryStr, new object[] {... parameters ...} ).Dump();,参数为@p0 ... @ 987654339@ 在查询字符串中。然后,您可以编写一个静态扩展类并将其保存在 My Extensions 下,以便在您的 LinqPad 查询中使用。数据上下文可以通过参数从查询窗口作为DataContextBase dc 传递,即公共静态扩展类中的public static void SearchDialog(this DataContextBase dc, string searchString = "%")(在LinqPad 6 中,它是DataContext)。然后您可以将上面的 SQL 查询重写为带有参数的字符串,并从 C# 上下文中调用它。

【讨论】:

  • 感谢您的努力。几乎完美。仅供参考 - 它不会返回那些在 insert into 语句中具有 column 引用的 SP。我发现这个答案更准确stackoverflow.com/a/8757152/9695286
  • @Karan - 我尝试了您提到的解决方案,但它没有返回任何结果。我在那里留下了评论。
【解决方案2】:

-- 搜索所有对象

SELECT OBJECT_NAME(OBJECT_ID),
definition
FROM sys.sql_modules
WHERE definition LIKE '%' + 'ColumnName' + '%'
GO

-- 仅在存储过程中搜索

SELECT DISTINCT OBJECT_NAME(OBJECT_ID)
FROM sys.Procedures
WHERE object_definition(OBJECT_ID) LIKE '%' + 'ColumnName' + '%'
GO

【讨论】:

    【解决方案3】:

    我遇到了同样的问题,我发现 Microsoft 有一个显示 dependenciessystable

    SELECT 
        referenced_id
        , referenced_entity_name AS table_name
        , referenced_minor_name as column_name
        , is_all_columns_found
    FROM sys.dm_sql_referenced_entities ('dbo.Proc1', 'OBJECT'); 
    

    这适用于ViewsTriggers

    【讨论】:

      【解决方案4】:

      一种选择是创建一个脚本文件。

      右击数据库->任务->生成脚本

      然后您可以选择所有存储过程并生成带有所有sps的脚本。所以你可以从那里找到参考。

      或者

      -- Search in All Objects
      SELECT OBJECT_NAME(OBJECT_ID),
      definition
      FROM sys.sql_modules
      WHERE definition LIKE '%' + 'CreatedDate' + '%'
      GO
      
      -- Search in Stored Procedure Only
      SELECT DISTINCT OBJECT_NAME(OBJECT_ID),
      object_definition(OBJECT_ID)
      FROM sys.Procedures
      WHERE object_definition(OBJECT_ID) LIKE '%' + 'CreatedDate' + '%'
      GO
      

      来源SQL SERVER – Find Column Used in Stored Procedure – Search Stored Procedure for Column Name

      【讨论】:

      • 这是否只是查找具有与WHERE 子句匹配的已定义参数的对象/过程,还是会在对象本身中找到对MyTable.SomeColumn 的引用?
      • 完美!对我很有用。谢谢
      【解决方案5】:

      您可以使用以下查询来识别值。但请记住,这不会为您提供加密存储过程的结果。

      SELECT DISTINCT OBJECT_NAME(comments.id) OBJECT_NAME
          ,objects.type_desc
      FROM syscomments comments
          ,sys.objects objects
      WHERE comments.id = objects.object_id
          AND TEXT LIKE '%CreatedDate%'
      ORDER BY 1
      

      【讨论】:

        【解决方案6】:

        您可以使用ApexSQL Search,它是一个免费的 SSMS 和 Visual Studio 插件,它可以列出所有引用特定表格列的对象。它还可以查找存储在表和视图中的数据。您可以轻松过滤结果以显示引用该列的特定数据库对象类型

        免责声明:我作为支持工程师在 ApexSQL 工作

        【讨论】:

        • 这不仅给出特定 SP 中名为 FirstName 的列,还给出任何 SP 中的列。这很好,除非您在多个表、视图中使用相同的列名......我知道没有工具可以找到引用特定列的每个位置。
        【解决方案7】:

        如果你想只使用特定列获取存储过程,你可以试试这个查询:

        SELECT DISTINCT Name
        FROM sys.Procedures
        WHERE object_definition(OBJECT_ID) LIKE '%CreatedDate%';
        

        如果您想使用表的特定列获取存储过程,可以使用以下查询:

        SELECT DISTINCT Name 
        FROM sys.procedures
        WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%tbl_name%'
        AND OBJECT_DEFINITION(OBJECT_ID) LIKE '%CreatedDate%';
        

        【讨论】:

          【解决方案8】:
          SELECT *
          FROM   sys.all_sql_modules
          WHERE  definition LIKE '%CreatedDate%'
          

          【讨论】:

            【解决方案9】:

            试试这个..

            SELECT Name
            FROM sys.procedures
            WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%CreatedDate%'
            GO
            

            或者您可以生成所有程序的脚本并从那里搜索。

            【讨论】:

              猜你喜欢
              • 2018-01-09
              • 1970-01-01
              • 2015-04-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-11-08
              • 2010-10-15
              相关资源
              最近更新 更多