在 SQL 服务器中查找丢失的 foreign/primary 键
Find missing foreign/primary keys in SQL Server
我正在寻找可以列出缺失 PK 和 FK 的查询。
我修改了 this query,最后得到了这个代码:
-- 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;
我的问题是关于第 40 行的:AND a.total_pages > 1.0
- 如果您注释掉该行,它将return你们都错过了 PK 和 FK
- 如果您使用该行,目标是 return 仅 table 大小 > 1MB
...而是 returning 也 tables 大小为 0.085937
您的条件是:
and a.total_pages > 1.0
但是您的 select 子句说:
a.total_pages / 128.00 AS Total_MB
如果您想过滤大于 1 MB 的大小,那么您可能需要以下条件:
and a.total_pages > 128
Table别名a
指的是sys.allocation_units
,它在一对left outer join
的右边。在不允许 null
值的 where
子句中使用它会将联接从 left outer
更改为 inner
。这将解释条件被注释掉时返回的“缺失”键行。
我正在寻找可以列出缺失 PK 和 FK 的查询。
我修改了 this query,最后得到了这个代码:
-- 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;
我的问题是关于第 40 行的:AND a.total_pages > 1.0
- 如果您注释掉该行,它将return你们都错过了 PK 和 FK
- 如果您使用该行,目标是 return 仅 table 大小 > 1MB
...而是 returning 也 tables 大小为 0.085937
您的条件是:
and a.total_pages > 1.0
但是您的 select 子句说:
a.total_pages / 128.00 AS Total_MB
如果您想过滤大于 1 MB 的大小,那么您可能需要以下条件:
and a.total_pages > 128
Table别名a
指的是sys.allocation_units
,它在一对left outer join
的右边。在不允许 null
值的 where
子句中使用它会将联接从 left outer
更改为 inner
。这将解释条件被注释掉时返回的“缺失”键行。