Wie finde ich alle Tabellen in einer Datenbank, die keinen expliziten Primärschlüssel haben?

10

Eine Google-Suche führte zu Millionen von Treffern beim Auffinden von Tabellen ohne Clustered-Index, wobei die PK normalerweise der Clustered-Index einer Tabelle ist. Eine Tabelle kann jedoch leicht einen natürlichen Schlüssel als Clustered-Index und einen nicht-Clustered-Surrogat-Index wie eine Identitätsspalte haben.

Wie finde ich alle Tabellen in einer Datenbank ohne definierten Primärschlüssel? Ich habe 245 Tabellen in dieser Datenbank: Die manuelle Überprüfung ist äußerst ineffizient.

ProfK
quelle

Antworten:

13

Einige Möglichkeiten, diese Katze zu häuten, aber dies funktioniert in SQL Server 2005 und höher einwandfrei, und ich finde es eine schmerzfreie Möglichkeit, das Problem zu lösen -

Die OBJECTPROPERTY()Funktion kann verschiedene Eigenschaften von Objekten wie Tabellen auflisten. Eine dieser Eigenschaften ist, ob eine Tabelle einen Primärschlüssel hat oder nicht.

OBJECTPROPERTY(object_id, tablehasprimarykey) = 0 wäre eine Tabelle ohne Primärschlüssel.

So

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

Sollte Ihnen geben, was Sie brauchen. Sie können alles über die anderen Möglichkeiten zur Verwendung der Funktion OBJECTPROPERTY () in Online-Büchern sehen. Dies ist die 2012-Version des Artikels.

Mike Walsh
quelle
Nun, die object_id wird funktionieren. Ich dachte, wir verwenden die Funktion. Aber die sys.tablesselbst gibt die ID und danke, dass Sie diese wunderbare Funktion gezeigt haben.
Biju Jose
Kein Problem. Es ist eine gute Funktion zu haben. Viele Eigenschaften. In diesem Fall haben Sie es richtig - sys.tables listet bereits die object_id darin auf. und das ist die object_id, die wir für den ID-Parameter an die OBJECTPROPERTY-Funktion übergeben möchten. Vielen Dank für den guten Fang des reservierten Schlüsselworts, das ich dort verwendet habe :)
Mike Walsh
Sie hatten genau Recht mit der Funktion object_id. Ich habe die Dinge dort nur durcheinander gebracht. Nun, danke, dass Sie darauf hingewiesen haben. Nun, die objectproperty()ist ab 2005 verfügbar. Ich habe gerade bol überprüft, oder?
Biju Jose
Ja. Dort in 2005 - 2014 und darüber hinaus zu diesem Zeitpunkt :-)
Mike Walsh
Ich habe das Skript bearbeitet, um den Schemanamen hinzuzufügen. Beachten Sie, dass (wie OBJECTPROPERTY) die Funktion OBJECT_SCHEMA_NAME () neu in MSSQL 2005 war.
Greenstone Walker
5

Mikes Lösung ist hervorragend für das spezifische Problem.

Wenn Sie mehr Flexibilität wünschen, hier ist eine Alternative , die leicht in eine Abfrage , dass die Renditen andere Informationen, wie die Suche nach allen Tabellen gemorpht werden können , die Haufen sind, oder die Suche nach Tabellen , die keine eindeutigen Einschränkungen haben überhaupt .

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)
        );

Sobald Ihr (Sub-) System über ~ 50 Tabellen verfügt, ist es wirklich wichtig, sich mit allen Metadatentabellen vertraut zu machen, da es, wie Sie sagten, unpraktisch (und fehleranfällig!) Ist, jede Tabelle manuell durchzugehen.

Jon Seigel
quelle
+1 für "weil es, wie Sie sagten, unpraktisch (und fehleranfällig!) Ist, jede Tabelle manuell durchzugehen." Amen da. Sehr fehleranfällig :)
Mike Walsh
4

Die Richtlinienverwaltungsfunktion von SQL Server kann einige davon ausführen.

Die Tabellenfacette enthält die Felder @HasIndex und @HasClusteredIndex (sowie andere nützliche Felder wie Trigger). Es kann eine Richtlinie erstellt werden, um die Bedingungen für alle Tabellen, in allen Datenbanken und auf mehreren Servern zu überprüfen (mithilfe der Funktion "Central Management Server").

Es kann jedoch nicht überprüft werden, ob ein Primärschlüsselindex oder eine Einschränkung vorhanden ist. Ich hätte geschworen, dass es ein Feld @HasPrimaryKey gibt, aber es ist in MSSQL2012 nicht vorhanden. Ich erinnere mich entweder falsch oder werde verrückt.

Hinweis: Die Richtlinienverwaltung ist in den Editionen SQL Server 2012 Enterprise, Business Intelligence und Standard enthalten. Es ist nicht in der Express Edition verfügbar.

Greenstone Walker
quelle
2
Ich denke, Sie könnten eine benutzerdefinierte Bedingung schreiben, die dies überprüft. +1 für einen ganz anderen Weg, dies zu tun.
Jon Seigel