如何查找数据库中没有显式主键的所有表?


10

一次Google搜索发出了数百万点击的信息,说明如何查找没有聚集索引的表,而PK通常是表的聚集索引。但是,表可以轻松地将自然键用作聚簇索引,并具有非聚簇代理索引(例如标识列)。

如何在未定义主键的数据库中查找所有表?我在该数据库中有245个表:手动检查效率很低。

Answers:


13

有几种方法可以给这只猫换皮,但是这种方法在SQL Server 2005及更高版本中都可以正常工作,我发现这是解决问题的一种轻松方法-

OBJECTPROPERTY()函数可以列出有关对象的各种属性-例如表。这些属性之一是表是否具有主键。

OBJECTPROPERTY(object_id, tablehasprimarykey) = 0将是一个没有主键的表。

所以

SELECT OBJECT_SCHEMA_NAME( object_id ) as SchemaName, name AS TableName
FROM sys.tables
WHERE OBJECTPROPERTY(object_id,'tablehasprimaryKey') = 0 
ORDER BY SchemaName, TableName ;

应该给你你所需要的。您可以在联机丛书中查看有关使用OBJECTPROPERTY()函数的所有其他方式的所有信息。这是本文的2012年版本。


我以为我们正在使用该函数,所以object_id很好用,但是sys.tables它本身给出了id,并感谢您展示了这个出色的功能。
Biju jose

没问题。这是一个很好的功能。很多属性。在这种情况下,您做对了-sys.tables已经在其中列出了object_id。那就是我们要传递给ID参数的object_id到OBJECTPROPERTY函数。感谢您在这里使用的保留关键字的好习惯:)
Mike Walsh

,对于object_id函数,您是完全正确的,我只是在上面混合了一些东西。谢谢您指出这一点。objectproperty()从2005年起就可以使用了,我刚刚检查了bol,对吗?
Biju jose

是。在2005年-2014年以及此后的时间:-)
Mike Walsh

我编辑了脚本以添加架构名称。需要注意的是(如OBJECTPROPERTY)的OBJECT_SCHEMA_NAME()函数是新的2005年MSSQL
绿宝石沃克

5

迈克的解决方案非常适合特定问题。

如果你想要更多的灵活性,这里是一个可以很容易演变成一个查询的替代方案,返回其他信息,如发现有堆所有表,或发现没有唯一约束的表在所有

SELECT
    OBJECT_SCHEMA_NAME(t.object_id) AS SchemaName,
    t.name AS TableName
    FROM sys.tables t
    WHERE
        NOT EXISTS
        (
            SELECT *
                FROM sys.indexes i
                WHERE
                    (i.object_id = t.object_id) AND
                    (i.is_primary_key = 1)
        );

一旦您的(子系统)表超过50个表,熟悉所有元数据表就非常重要,因为正如您所说,手动浏览每个表是不切实际的(而且容易出错!)。


+1表示“因为如您所说,手动浏览每个表是不切实际的(而且容易出错!)。” 阿们在那里。非常容易出错:)
Mike Walsh

4

SQL Server 的策略管理功能可以做到这一点。

Table方面包含@HasIndex和@HasClusteredIndex字段(以及其他可能有用的字段,例如触发器)。可以创建一个策略来检查许多服务器(使用中央管理服务器功能)中所有表,所有数据库中的条件。

但是,它无法检查主键索引或约束的存在。我会发誓那里没有@HasPrimaryKey字段,但MSSQL2012中没有。我要么记错了要么发疯了。

注意:策略管理包含在SQL Server 2012 Enterprise,Business Intelligence和Standard版本中。Express版本不提供此功能。


2
我认为您可以编写一个自定义条件来检查这一点。+1是一种完全不同的方法。
乔恩·塞格尔
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.