简体   繁体   English

在 SQL Server 中查找丢失的外键/主键

[英]Find missing foreign/primary keys in SQL Server

I'm lookin for a query that could list missing PK and FK.我正在寻找一个可以列出丢失的 PK 和 FK 的查询。

I modified this query and I ended up with this code:我修改了这个查询,最后得到了这个代码:

-- Find columns on tables with names like FooID or FooCode which should
-- be part of primary or foreign keys, but aren't.
SELECT t.name AS [Table], 
       c.name AS [Column], 
       a.total_pages / 128.00 AS Total_MB
FROM sys.tables t
     INNER JOIN sys.syscolumns c ON c.id = t.object_id               
     -- Join on foreign key columns        
     LEFT JOIN sys.foreign_key_columns fkc ON(fkc.parent_object_id = t.object_id
                                              AND c.colid = fkc.parent_column_id)
                                             OR (fkc.referenced_object_id = t.object_id
                                                 AND c.colid = fkc.referenced_column_id)                
     -- Join on primary key columns        
     LEFT JOIN sys.indexes i ON i.object_id = t.object_id
                                AND i.is_primary_key = 1
     LEFT JOIN sys.index_columns ic ON ic.object_id = t.object_id
                                       AND ic.index_id = i.index_id
                                       AND ic.column_id = c.colid
     INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID
                                    AND i.index_id = p.index_id
     INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id
WHERE t.is_ms_shipped = 0
      AND (c.name LIKE '%ID'
           OR c.name LIKE '%Code')
      AND (fkc.constraint_object_id IS NULL 
           -- Not part of a foreign key                 
           AND ic.object_id IS NULL 
      -- Not part of a primary key        
      )
      AND (                
      -- Ignore some tables                
      t.name != 'sysdiagrams'
      AND t.name NOT LIKE '[_]%' 
      -- temp tables                
      AND t.name NOT LIKE '%temp%'
      AND t.name NOT LIKE '%Log%' 
      -- log tables                                
      -- Ignore some columns                
      AND c.name NOT IN('GLCode', 'EID', 'AID'))
     AND a.total_pages > 1.0
-- external keys        
ORDER BY t.name, 
         c.name;

My question is all about line 40: AND a.total_pages > 1.0我的问题是关于第 40 行: AND a.total_pages > 1.0

  • If you comment out that line it will return you all missing PK and FK如果您注释掉该行,它将返回您所有丢失的 PK 和 FK
  • If you use that line the goal is to return only table which have size > 1MB如果您使用该行,则目标是仅返回大小 > 1MB 的表

...but instead is returning also tables with size 0.085937 ...但相反还返回了大小为 0.085937 的表

在此处输入图片说明

Your condition is:你的情况是:

and a.total_pages > 1.0

But your select clause says:但是您的选择条款说:

a.total_pages / 128.00 AS Total_MB

If you want to filter on sizes that are greatest than 1 MB, then you probably want this condition instead:如果要过滤大于 1 MB 的大小,则可能需要以下条件:

and a.total_pages > 128

Table alias a refers to sys.allocation_units which is on the right side of a couple of left outer join s.表别名a指的是sys.allocation_units ,它位于几个left outer joinleft outer join Using it in the where clause without allowing for null values changes the joins from left outer to inner .where子句中使用它而不允许null值将连接从left outer更改为inner That would account for the "missing" key rows being returned when the condition is commented out.这将解释当条件被注释掉时返回的“丢失”关键行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM