Für Access- und SQL-Server-Entwickler, die Kommentare schreiben können, aber nie sicher waren, wo sie eigentlich hingehören.
Worum es geht
Wer in Access Module schreibt, kommentiert. Wer T-SQL schreibt, kommentiert auch — meistens als ---Zeile über einer Stored Procedure, manchmal als Block am Anfang. Das Problem ist nicht, dass dokumentiert wird. Das Problem ist, wo die Doku landet: in der Datei, mit der die Prozedur ursprünglich angelegt wurde. Diese Datei liegt auf einem Netzlaufwerk, in einem Quellcode-Repository, oder gar nicht — und im SQL Server selbst ist davon nichts zu sehen. Wer ein Jahr später sp_helptext auf die Prozedur aufruft, bekommt den Code mit den Kommentaren zurück, falls das Original-Skript verwendet wurde, um die Prozedur anzulegen. Wer eine Tabelle mit SELECT * FROM sys.tables ansieht, bekommt Namen, Datum, Größe — keine Beschreibung.
SQL Server hat seit Version 2000 einen eingebauten, leise eingeführten und seitdem nie groß beworbenen Mechanismus für genau dieses Problem:
Extended Properties. Sie sind das, was Rubberduck-Annotations für VBA sind — eine strukturierte Doku, die am Objekt selbst lebt und überall mitfährt, wo das Objekt hinfährt: Backup, Restore, Migration, Skript-Export. Und sie sind im KMU-Bereich erstaunlich selten ausgeschöpft, obwohl sie nichts kosten und mit jedem SQL Server kommen.
Dieser Beitrag erklärt, wie sie funktionieren, wie der inoffizielle Standard heißt, wie man sie handgeschrieben pflegt und welche Werkzeuge das angenehmer machen.
Was Extended Properties sind
Eine Extended Property ist ein Name-Wert-Paar, das an ein Datenbankobjekt geheftet wird. Der Name ist frei wählbar, der Wert kann bis zu 7500 Bytes lang sein und ist intern ein sql_variant. Das Schöne: Microsoft hat keine Liste von erlaubten Properties festgelegt. Du darfst beliebige Namen erfinden, beliebige Werte ablegen, an beliebige Objekte hängen. Was du nicht selbst entscheiden musst, ist die Konvention für die Beschreibung — dafür hat sich MS_Description als Quasi-Standard etabliert. SSMS zeigt diese Property in den Eigenschaften-Dialogen automatisch an, alle gängigen Doku-Werkzeuge lesen sie, und alle Backup-/Restore-Mechanismen nehmen sie mit.
Eine Extended Property kann an folgenden Objekten hängen: an der Datenbank selbst, an Schemas, an Tabellen, an einzelnen Spalten, an Indizes, an Constraints, an Views, an Stored Procedures, an Functions, an Triggern, an Parametern von Prozeduren und Functions. Das deckt praktisch alles ab, was in einer Anwendungs-Datenbank lebt. Eine Ausnahme gibt es: an Memory-Optimized Tables sind sie nicht erlaubt — ein Spezialfall, der im KMU-Bereich kaum vorkommt.
Die zentrale Eigenschaft: Extended Properties werden mit der Datenbank gesichert. Sie liegen in der Systemtabelle sys.extended_properties, sie sind Teil des Datenbank-Backups, sie überleben jeden Restore. Wer eine dokumentierte Datenbank von einem Server auf einen anderen umzieht, nimmt die Doku mit, ohne darüber nachzudenken. Das ist der entscheidende Unterschied zu Kommentaren in Skript-Dateien: die Doku gehört zur Datenbank, nicht zum Skript.
Wie man sie schreibt — die ehrliche Wahrheit
Microsoft hat die Bedienung dieses guten Mechanismus mit einer Bedienoberfläche ausgestattet, die nur ein Microsoft-Mitarbeiter wirklich lieben kann. Es gibt drei Stored Procedures:
EXEC sp_addextendedproperty
@name = N'MS_Description',
@value = N'Stammdaten der Kunden, Eintrag pro juristische Einheit.',
@level0type = N'SCHEMA', @level0name = N'dbo',
@level1type = N'TABLE', @level1name = N'Kunden';
Das ist die einfache Variante: eine Beschreibung an die Tabelle dbo.Kunden. Das @level0 ist das Schema, @level1 ist die Tabelle. Eine Spalte braucht eine zusätzliche Stufe:
EXEC sp_addextendedproperty
@name = N'MS_Description',
@value = N'Eindeutiger Identifikator, vergeben aus Sequenz.',
@level0type = N'SCHEMA', @level0name = N'dbo',
@level1type = N'TABLE', @level1name = N'Kunden',
@level2type = N'COLUMN', @level2name = N'KundeID';
Das funktioniert. Es ist nur eben nicht das, was man als „mal eben dokumentieren“ bezeichnen würde. Drei Dinge fallen sofort auf: erstens sind die Aufrufe lang. Zweitens muss man wissen, welche Hierarchie-Stufe das Objekt hat, das man dokumentieren will (Schemas und User sind level 0, Tabellen und Views und Procedures sind level 1, Spalten und Parameter sind level 2). Drittens — und das ist der unangenehmste Punkt — gibt es drei separate Procedures: sp_addextendedproperty für neue Properties, sp_updateextendedproperty zum Ändern, sp_dropextendedproperty zum Löschen. Das add schlägt fehl, wenn die Property schon existiert; das update schlägt fehl, wenn sie noch nicht existiert. Wer ein Skript schreibt, das eine Doku idempotent setzen soll („egal ob neu oder Update — am Ende soll diese Beschreibung dastehen“), muss vorher abfragen oder mit Fehlern hantieren.
Dafür gibt es ein gängiges Muster, das man einmal in eine eigene Helper-Procedure packt und danach immer verwendet:
CREATE OR ALTER PROCEDURE dbo.sp_setdescription
@description NVARCHAR(MAX),
@level0type SYSNAME, @level0name SYSNAME,
@level1type SYSNAME = NULL, @level1name SYSNAME = NULL,
@level2type SYSNAME = NULL, @level2name SYSNAME = NULL
AS
BEGIN
IF EXISTS (
SELECT 1 FROM fn_listextendedproperty(
N'MS_Description',
@level0type, @level0name,
@level1type, @level1name,
@level2type, @level2name
)
)
EXEC sp_updateextendedproperty
@name = N'MS_Description', @value = @description,
@level0type = @level0type, @level0name = @level0name,
@level1type = @level1type, @level1name = @level1name,
@level2type = @level2type, @level2name = @level2name;
ELSE
EXEC sp_addextendedproperty
@name = N'MS_Description', @value = @description,
@level0type = @level0type, @level0name = @level0name,
@level1type = @level1type, @level1name = @level1name,
@level2type = @level2type, @level2name = @level2name;
END
Mit dieser Hilfsprozedur lebt der Aufruf in einer Zeile, und das Skript wird bei jedem Lauf idempotent — egal ob die Property schon existiert oder nicht, am Ende steht der gewünschte Text. Das ist die Form, in der eine Doku-Pflege überhaupt zumutbar wird.
Wie man sie liest
Hier wird es wieder einfacher. Die Property liegt in sys.extended_properties, und mit einem Join auf sys.objects und sys.columns (oder sys.schemas für die höchste Ebene) kommt man an alles ran, was man braucht. Eine pragmatische Abfrage für „alle dokumentierten Tabellen einer Datenbank“:
SELECT
SCHEMA_NAME(t.schema_id) + '.' + t.name AS Tabelle,
CAST(ep.value AS NVARCHAR(MAX)) AS Beschreibung
FROM sys.tables t
LEFT JOIN sys.extended_properties ep
ON ep.major_id = t.object_id
AND ep.minor_id = 0
AND ep.class = 1
AND ep.name = N'MS_Description'
WHERE t.is_ms_shipped = 0
ORDER BY Tabelle;
class = 1 heißt „Objekt oder Spalte“, minor_id = 0 filtert die Tabelle selbst (eine Spalte hätte hier ihre Spalten-ID). Der Rest ist Geschmackssache. Eine ähnliche Abfrage für Spalten ergibt sich, wenn man sys.columns mitnimmt und minor_id = c.column_id setzt.
Was SSMS daraus macht: in den Eigenschaften eines Objekts (Rechtsklick → Eigenschaften → Erweiterte Eigenschaften) sind Extended Properties direkt sichtbar und editierbar. Bei Spalten verbirgt sie sich tiefer, im Tabellen-Designer unter „Beschreibung“ — derselbe Mechanismus, andere Bezeichnung. Die Microsoft-eigenen Werkzeuge nehmen diese Properties also wahr; sie machen es nur nicht angenehm.
Welche Werkzeuge das einfacher machen
Hier wird die Lage vergleichsweise gut — anders als bei VBA und Rubberduck gibt es im SQL-Server-Umfeld eine etablierte Werkzeug-Landschaft, die seit Jahren stabil ist. Die wichtigsten Kandidaten:
Redgate SQL Doc ist der unangefochtene Marktführer. Liest und schreibt Extended Properties direkt, generiert HTML- und PDF-Dokumentationen, und macht die Editiererei zu einer angenehmen Klick-Übung. Kostet als Einzelprodukt einige hundert Euro, ist Teil des Redgate SQL Toolbelt für mehr. Für den KMU-Einsatz ein gerechtfertigter Posten, wenn man mehrere Datenbanken pflegt.
ApexSQL Doc (inzwischen unter Quest Software) ist die direkte Alternative — funktional vergleichbar, ähnliches Preisspektrum, mit einem zusätzlichen kostenlosen SSMS-Add-In namens ApexSQL Search, das Extended Properties bearbeiten kann, ohne dass man die volle Suite kauft. Wer nur die Editiererei vereinfachen will, kommt damit ohne Lizenzkosten aus.
Dataedo ist ein anderer Ansatz: ein eigenes Repository, in dem die Doku unabhängig von der Datenbank lebt, mit der Möglichkeit, sie auf Wunsch in die Extended Properties zu schreiben. Charmant für Organisationen, die mehrere Datenbanken zentral dokumentieren wollen. Für eine einzelne Anwendungs-DB im KMU-Bereich Overkill.
Data Dictionary Creator (DDC) ist ein freies, schlankes Werkzeug, das sich auf Tabellen und Spalten beschränkt. Hat keine HTML-Generierung, keine Reports, dafür einen klaren Fokus: Beschreibungen pflegen, in Extended Properties speichern. Wer nur das eine Bedürfnis hat, ist hier richtig.
SchemaSpy ist quelloffen, kostenlos, und erzeugt eine durchsuchbare HTML-Doku einer Datenbank — inklusive Beziehungsdiagrammen. Liest auch Extended Properties, schreibt sie aber nicht. Das ist die Reporting-Seite, nicht die Pflege-Seite.
Eine ehrliche Einordnung für den KMU-Bereich: wer eine Datenbank ernsthaft pflegt, kommt mit der Kombination aus einer eigenen Helper-Procedure (siehe oben) plus einem freien Werkzeug für die Übersicht (SchemaSpy oder DDC) erstaunlich weit. Wer mehrere Datenbanken hat oder regelmäßig Reports an Auftraggeber liefert, dem zahlt sich Redgate SQL Doc nach kurzer Zeit aus.
Was Extended Properties nicht können
Damit die Erwartung stimmt, hier die ehrlichen Lücken:
Keine Versionierung. Eine Extended Property ist immer der aktuelle Stand. Wer wissen will, wann eine Beschreibung wie geändert wurde, braucht ein externes Repository oder eine eigene History-Tabelle. Quellcode-Verwaltung der Doku passiert nicht im SQL Server.
Keine Referenzen. Eine Beschreibung ist Text. Wenn in der Beschreibung von Tabelle A auf Tabelle B verwiesen wird, weiß SQL Server nichts von dieser Verbindung. Wer relationale Doku will („Tabelle A wird von Procedure X verwendet“), braucht andere Mittel — etwa Abfragen über sys.sql_dependencies oder ein externes Werkzeug, das den Code parst.
Keine Strukturierung. Eine Property ist ein Name und ein Wert. Wer mehr will — Argumente, Rückgabewerte, Beispiel-Aufrufe, Versionshistorie — muss sich selbst ein Schema im Kopf zurechtlegen und die Beschreibung entsprechend formatieren. Markdown im MS_Description-Feld ist gängige Praxis, aber kein Standard. Manche pflegen eigene Properties: Author, LastReviewed, BusinessOwner. Das geht — aber Werkzeuge wie SQL Doc zeigen sie dann nicht ohne Konfiguration.
Keine Pflicht. Es gibt keinen Mechanismus, der das Anlegen einer neuen Tabelle ohne Beschreibung verhindert. Disziplin schlägt Werkzeug — wer keine Routine etabliert, in der jede Schema-Änderung die Doku mitführt, hat in zwei Jahren wieder den alten Zustand.
Der praktische Pfad — drei Stufen
Aus der Praxis heraus würde ich folgenden Einstieg empfehlen, sortiert von „heute Nachmittag“ zu „mittelfristige Disziplin“:
Stufe 1: Helper-Procedure einrichten. Die sp_setdescription von oben in jede Datenbank, die du betreust. Damit wird das Setzen einer Beschreibung zu einem Einzeiler. Allein dieser Schritt entscheidet darüber, ob du je eine zweite Property pflegst.
Stufe 2: Schema-Skripte um Doku-Aufrufe ergänzen. Wenn du eine Tabelle anlegst oder änderst, gehört der EXEC dbo.sp_setdescription-Aufruf in dasselbe Skript. Eine Tabelle ohne Beschreibung ist ein unfertiges Skript. Das kostet pro Tabelle eine Minute, einmalig.
Stufe 3: Lese-Reports etablieren. Eine SELECT-Abfrage über sys.extended_properties, die alle dokumentierten und nicht-dokumentierten Objekte listet, hängt an einer Stelle, die du regelmäßig ansiehst. Dann ist die nächste „undokumentierte Spalte“ sofort sichtbar — und du fügst sie ergänzen kannst, bevor sie vergessen wird.
Wer diese drei Stufen geht, hat nach drei Monaten eine durchgängig beschriebene Datenbank, ohne dass es sich nach Großprojekt angefühlt hat.
Was bleibt
Extended Properties sind eines der nützlichsten und am wenigsten beworbenen Features im SQL Server. Sie sind seit über zwanzig Jahren da, sie funktionieren in jeder Edition (auch Express), sie überleben Backups und Migrationen, und mit einer kleinen eigenen Helper-Procedure ist die Bedienung erträglich. Der einzige Grund, warum sie so selten gepflegt werden, ist die historische Trägheit der Stored Procedures, mit denen Microsoft sie ursprünglich ausgestattet hat — und die hat man in fünfzehn Minuten umschifft.
Wer Access-Anwendungen mit SQL-Server-Backend betreut, hat jetzt eine angenehme Symmetrie: in Access pflegen Rubberduck-Annotations die Doku am Code, im SQL Server pflegen Extended Properties die Doku am Objekt. Beides am richtigen Ort, beides werkzeugauswertbar, beides überlebt das Werkzeug, mit dem es gepflegt wurde. Was fehlt, ist die Klammer darüber — ein Mechanismus, der Doku in beiden Welten gemeinsam erfasst, in eine Form bringt und gegen die Realität abgleicht.
Genau daran arbeite ich gerade. Mehr dazu, wenn es etwas zu zeigen gibt.
Sönke Schäfer · Datenschäfer · sesoft.de



