【问题标题】:find all tables not referenced in stored procedures查找存储过程中未引用的所有表
【发布时间】:2011-03-18 13:03:20
【问题描述】:

我有很多表的 sql server 数据库,有些不再使用,所以我想删除它们。所有数据库交互都是通过这些表的存储过程。

是否有我可以使用的数据库 sql 脚本来列出数据库中任何存储过程中未引用的所有表?

【问题讨论】:

  • 这个问题与this one几乎相同,但答案不同。
  • @DOK - 哪一个?您已链接回此问题!
  • @Martin 谢谢你的收获。 This one,在 Mitul 的回答中引用,是 dup。
  • @DOK:这可能是一个关于递归的问题的好笑话。

标签: sql sql-server stored-procedures


【解决方案1】:

如果您使用任何动态 T-SQL,则无法执行此操作。动态 T-SQL 不会出现在任何对象依赖关系的调查中。

相反,您可以使用 DMV sys.dm_db_index_usage_stats 来查找尚未被任何查询引用的对象。这是我在 SQLServerPedia 上为此所做的查询:

http://sqlserverpedia.com/wiki/Find_Indexes_Not_In_Use

该查询是为性能调优索引而设计的,因此您需要调整几行。这是修改后的查询:

SELECT 
o.name
, indexname=i.name
, i.index_id   
, reads=user_seeks + user_scans + user_lookups   
, writes =  user_updates   
, rows = (SELECT SUM(p.rows) FROM sys.partitions p WHERE p.index_id = s.index_id AND s.object_id = p.object_id)
, CASE
    WHEN s.user_updates < 1 THEN 100
    ELSE 1.00 * (s.user_seeks + s.user_scans + s.user_lookups) / s.user_updates
  END AS reads_per_write
, 'DROP INDEX ' + QUOTENAME(i.name) 
+ ' ON ' + QUOTENAME(c.name) + '.' + QUOTENAME(OBJECT_NAME(s.object_id)) as 'drop statement'
FROM sys.dm_db_index_usage_stats s  
INNER JOIN sys.indexes i ON i.index_id = s.index_id AND s.object_id = i.object_id   
INNER JOIN sys.objects o on s.object_id = o.object_id
INNER JOIN sys.schemas c on o.schema_id = c.schema_id
WHERE OBJECTPROPERTY(s.object_id,'IsUserTable') = 1
AND s.database_id = DB_ID()   
ORDER BY reads

请记住,这会捕获所有索引,您需要进行筛选 - 您的一些对象可能是堆,一些可能有聚集索引,等等。我将把它作为一个 wiki 保留,以便有人比我可以对其进行编辑以构建重复数据删除列表。 :-D

【讨论】:

    【解决方案2】:

    如果是 SQL Server 2008,那么依赖关系信息现在是可靠的。

    SELECT SCHEMA_NAME(t.schema_id),
           t.name
    FROM   sys.tables t
    WHERE  is_ms_shipped = 0
           AND NOT EXISTS (SELECT *
                           FROM   sys.sql_expression_dependencies d
                           WHERE  d.referenced_entity_name = t.name
                                  AND (( is_ambiguous = 1 or is_caller_dependent=1)
                                         OR
                              d.referenced_id = t.object_id)  )
    

    【讨论】:

    • 跨数据库依赖是否准确?我以为他们还没有
    • @JNK - 在sys.sql_expression_dependencies 中有一个referenced_database_name 可以查看。我在回答中根本没有考虑到这一点,另外,如果 OP 的任何列的名称与他们的表之一完全相同,我的回答也需要调整。我已经把它作为 OP 的练习!
    【解决方案3】:

    查看此讨论tsql script to find tables not being used by stored procedures, views, functions, etc?

    这篇文章(从上面的讨论中列出)http://www.mssqltips.com/tip.asp?tip=1294 讨论了 SQL 对象依赖关系。

    【讨论】:

      【解决方案4】:

      大概是这样的:

      select t.table_name
      from INFORMATION_SCHEMA.TABLES t
      where not exists (
          select 1 from INFORMATION_SCHEMA.ROUTINES r
          where object_definition(object_id(r.ROUTINE_NAME)) like '%'+t.TABLE_NAME+'%'
      ) order by t.TABLE_NAME
      

      【讨论】:

        【解决方案5】:

        第一个查询列出了使用它的存储过程名称的表。 第二个查询列出了表以及使用它的存储过程的数量。

        -- list all tables / sprocs
        select t.name [Table], p.name [StoredProc]
        from sys.tables t 
        left join sys.procedures p on (OBJECT_DEFINITION(p.object_id)) like '%' + t.name + '%'
        where t.type = 'U'
        order by t.name, p.name
        
        -- count stored procs using table
        select t.name [Table], count(p.name) [Count]
        from sys.tables t 
        left join sys.procedures p on (OBJECT_DEFINITION(p.object_id)) like '%' + t.name + '%'
        where t.type = 'U'
        group by t.name
        order by t.name
        

        【讨论】:

          【解决方案6】:

          你可以试试这个:

          select 
              name
          from 
                  sys.tables t
              left join
                  sys.sql_dependencies d
              on
                  t.object_id = 
                  d.referenced_major_id
          where 
              d.referenced_major_id is null
          

          否则,这是我过去使用的参考:

          http://www.mssqltips.com/tip.asp?tip=1294

          【讨论】:

            【解决方案7】:

            如果性能问题不大,您可以尝试以下方法。

            Select  Distinct Object_Name(ID)
            From    syscomments
            Where   ID Not In (Select ID From syscomments Where Text Like '%<TableName>%')
            

            这将检查数据库中的每个视图、规则、默认值、触发器、CHECK 约束、DEFAULT 约束和存储过程

            【讨论】:

              【解决方案8】:

              如果存在“dbo”以外的架构,或者用户的默认架构不是“dbo”,则大部分代码都不起作用。以下是修复该问题的脚本之一的更新:

              select t.Table_Schema + '.' + t.table_name
              from INFORMATION_SCHEMA.TABLES t
              where not exists (
                  select 1 from INFORMATION_SCHEMA.ROUTINES r
                  where object_definition(object_id(r.routine_schema + '.' + r.ROUTINE_NAME)) like '%'+t.TABLE_NAME+'%'
              ) order by t.TABLE_NAME
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2018-01-09
                • 1970-01-01
                • 1970-01-01
                • 2013-11-01
                • 2010-10-29
                • 2011-02-19
                • 2014-10-25
                • 1970-01-01
                相关资源
                最近更新 更多