MSSQL Meta-Daten beschreiben die Struktur und Eigenschaften einer SQL-Server-Datenbank: Welche Tabellen und Spalten gibt es? Welche Indizes oder Fremdschlüssel sind definiert? Solche Informationen brauchst du, wenn du eine unbekannte Datenbank verstehen, Änderungen vorbereiten oder eine technische Dokumentation erstellen möchtest. SQL Server stellt sie unter anderem über sys-Katalogansichten und INFORMATION_SCHEMA bereit.

Dieser Beitrag zeigt, wie du MSSQL Meta-Daten mit ausführbaren T-SQL-Abfragen für Tabellen, Spalten, Indizes und Beziehungen ausliest. Er erklärt außerdem, weshalb ein fehlendes Ergebnis nicht immer bedeutet, dass ein Objekt nicht existiert: Die Sicht auf Metadaten hängt auch von Berechtigungen und dem gewählten Datenbankkontext ab.

Was sind MSSQL Meta-Daten?

Metadaten sind Informationen über Datenbankobjekte. Eine Kundentabelle enthält beispielsweise Namen und Adressen. Zu ihren Metadaten gehören dagegen der Tabellenname, ihre Spalten und Datentypen, ein Primary Key sowie vorhandene Indizes. Auch Definitionen von Views und Prozeduren oder hinterlegte Beschreibungen gehören dazu.

Davon zu unterscheiden sind Laufzeitinformationen wie aktuell ausgeführte Abfragen, Wartezeiten oder Indexnutzung. Sie stammen häufig aus Dynamic Management Views (DMVs), Query Store oder Extended Events und können sich mit dem Serverzustand ändern. Ein Verzeichnis der Tabellen ist keine Zugriffsprotokollierung: Es verrät nicht automatisch, welcher Benutzer eine Zeile zu welchem Zeitpunkt gelesen hat.

Welche Quellen für SQL-Server-Metadaten gibt es?

Quelle Geeignet für Wichtige Grenze
sys-Katalogansichten SQL-Server-spezifische Objektdefinitionen, Spalten, Indizes, Constraints Zeigen nur Objekte, deren Metadaten für deinen Benutzer sichtbar sind
INFORMATION_SCHEMA Einfache, standardnahe Listen etwa von Tabellen und Spalten Deckt nicht alle SQL-Server-Funktionen und Eigenschaften ab
DMVs und DMFs Aktueller Zustand, Aktivität und Diagnosewerte Benötigen teils zusätzliche Rechte; Werte sind nicht automatisch ein dauerhaftes Protokoll
SSMS-Objekt-Explorer Grafische Erkundung einzelner Objekte Zeigt dieselben Berechtigungsgrenzen; für wiederholbare Inventare sind Abfragen praktischer
Extended Events Gezielte Erfassung von Ereignissen und Aktivitäten Muss passend eingerichtet und gefiltert werden; ist keine reine Schemaansicht

Für SQL Server sind die Katalogansichten meist die erste Wahl, wenn du ein vollständigeres Bild der Objektstruktur brauchst. Microsoft weist darauf hin, dass INFORMATION_SCHEMA nur einen Teil der Metadaten abbildet und nicht zuverlässig zur Ermittlung sämtlicher Schemaeigenschaften geeignet ist. Die Dokumentation zu INFORMATION_SCHEMA.TABLES nennt diese Einschränkung ausdrücklich.

Vor der Abfrage: Datenbankkontext prüfen

Die meisten folgenden Ansichten beziehen sich auf die aktuelle Datenbank. Prüfe deshalb zuerst, wo dein Abfragefenster verbunden ist:

SELECT DB_NAME() AS AktuelleDatenbank;

Wähle anschließend in SQL Server Management Studio die gewünschte Datenbank aus oder setze den Kontext mit einer passenden USE-Anweisung. Die folgenden Abfragen sind lesend und ändern keine Datenbankobjekte.

Tabellen und Schemas mit sys.tables auflisten

Diese Abfrage nennt alle für dich sichtbaren Benutzertabellen der aktuellen Datenbank samt Schema:

SELECT s.name AS SchemaName,
       t.name AS Tabellenname,
       t.create_date AS ErstelltAm,
       t.modify_date AS GeaendertAm
FROM sys.tables AS t
INNER JOIN sys.schemas AS s
    ON s.schema_id = t.schema_id
ORDER BY s.name, t.name;

Gib das Schema immer mit an: dbo.Kunden und archiv.Kunden wären verschiedene Objekte. modify_date ist ein Metadaten-Zeitstempel; bei Tabellen kann ihn auch das Erstellen oder Ändern eines gruppierten Index beeinflussen. Er zeigt nicht den Zeitpunkt der letzten Datenänderung an.

Für eine einfache, standardnahe Übersicht kannst du auch Folgendes verwenden:

SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_SCHEMA, TABLE_NAME;

Bei SQL-Server-spezifischen Eigenschaften solltest du anschließend zu den passenden sys-Ansichten wechseln.

Spalten, Datentypen und NULL-Eigenschaften auslesen

sys.columns enthält eine Zeile pro Spalte. Verbinde die Ansicht mit sys.tables, sys.schemas und sys.types, um verständliche Namen zu erhalten. Die folgende Abfrage begrenzt die Ausgabe auf die ersten 100 sichtbaren Spalten:

SELECT TOP (100)
       s.name AS SchemaName,
       t.name AS Tabellenname,
       c.column_id AS Spaltenposition,
       c.name AS Spaltenname,
       ty.name AS Datentyp,
       c.max_length AS MaxLaengeBytes,
       c.is_nullable AS ErlaubtNull,
       c.is_identity AS IstIdentity
FROM sys.tables AS t
INNER JOIN sys.schemas AS s
    ON s.schema_id = t.schema_id
INNER JOIN sys.columns AS c
    ON c.object_id = t.object_id
INNER JOIN sys.types AS ty
    ON ty.user_type_id = c.user_type_id
ORDER BY s.name, t.name, c.column_id;

max_length wird in Bytes angegeben, nicht pauschal in Zeichen. Bei nvarchar sind beispielsweise für viele Zeichen zwei Bytes vorgesehen; -1 steht bei geeigneten Datentypen für MAX. Für ein Dokumentationswerkzeug solltest du Länge, Präzision und Skalierung je nach Datentyp getrennt auswerten. is_identity sagt nur, ob eine Spalte als IDENTITY definiert ist; sie ist deshalb nicht automatisch ein Primary Key.

Indizes und ihre Spalten anzeigen

Ein Indexinventar zeigt Typ, Eindeutigkeit und Schlüsselspalten. Dieses Beispiel betrachtet Clustered und Nonclustered Rowstore-Indizes und begrenzt die Ausgabe auf 100 Zeilen:

SELECT TOP (100)
       s.name AS SchemaName,
       t.name AS Tabellenname,
       i.name AS Indexname,
       i.type_desc AS Indextyp,
       i.is_unique AS IstEindeutig,
       i.is_primary_key AS IstPrimaryKey,
       c.name AS Spaltenname,
       ic.key_ordinal AS Schluesselposition,
       ic.is_included_column AS IstIncludeSpalte
FROM sys.tables AS t
INNER JOIN sys.schemas AS s
    ON s.schema_id = t.schema_id
INNER JOIN sys.indexes AS i
    ON i.object_id = t.object_id
INNER JOIN sys.index_columns AS ic
    ON ic.object_id = i.object_id
   AND ic.index_id = i.index_id
INNER JOIN sys.columns AS c
    ON c.object_id = ic.object_id
   AND c.column_id = ic.column_id
WHERE i.type IN (1, 2)
ORDER BY s.name, t.name, i.name,
         ic.key_ordinal, ic.index_column_id;

key_ordinal beschreibt die Position einer Indexschlüsselspalte. Eine INCLUDE-Spalte ist über is_included_column = 1 erkennbar. Implizit hinzugefügte Clustered-Schlüsselspalten erscheinen laut Microsoft-Dokumentation zu sys.index_columns nicht immer als eigene Zeilen dieser Ansicht. Die Abfrage zeigt außerdem bewusst keine Columnstore-, XML- oder anderen speziellen Indextypen.

Dass ein Index existiert, bedeutet noch nicht, dass Abfragen ihn tatsächlich nutzen. Für Indexnutzung und Wartung lies die Indexanalyse im SQL Server; bei langsamen Abfragen hilft die Diagnose mit Query Store und Ausführungsplänen.

Fremdschlüssel und Tabellenbeziehungen finden

sys.foreign_keys enthält die Constraints, sys.foreign_key_columns ihre Spaltenpaare. Die folgende Abfrage zeigt, welche Spalte auf welche andere verweist: