Quick and Dirty Datenbank Dokumentierer

Immer wieder liest man Fragen, wie man über alle Datenbanken einer Instanz hinweg, alle Tabellen plus Spalten und deren Datentypen usw... auslesen kann

...

Um all diesen Personen die schwierigen Bedienung einer Internet-Suchmaschine abzunehmen ist hier ein Skript, das ich in 10 Minuten gerade geschrieben habe. Es erhebt keinerlei Anspruch auf Effektivität, Fehlerfreiheit, Vollständigkeit und/oder ähnliches, sondern soll vielmehr als Denkanstoss dienen.

DECLARE @Databases TABLE (dbname sysname);
DECLARE @Database sysname;
DECLARE @DatabaseCmd sysname;
DECLARE @sql nvarchar(2000)

INSERT INTO @Databases
    (dbname)
SELECT
    D.name
FROM
    sys.databases D
WHERE
    D.database_id > 5    


SELECT
    @Database = MIN(D.dbname),
    @DatabaseCmd = @Database + '.sys.sp_ExecuteSQL'
FROM
    @Databases D;

WHILE @Database IS NOT NULL
BEGIN
    SELECT @sql = '
    SELECT
        DB_NAME() as CurrentDatabase,
        O.name AS TableName,
        C.name AS ColumnName,
        C.column_id,
        S.name,
        S.length,
        C.precision,
        C.scale,
        C.is_nullable
    FROM
        sys.objects O
        JOIN
        sys.columns C ON O.object_id = C.object_id
        JOIN
        sys.systypes S ON C.system_type_id = S.xtype
    WHERE
        O.type = ''U'' AND
        O.is_ms_shipped = 0
    ORDER BY
        O.name,
        C.column_id'

    EXEC @DatabaseCmd @sql;
    
    DELETE
        @Databases
    WHERE
        dbname = @Database;
        
    SELECT
        @Database = MIN(D.dbname),
        @DatabaseCmd = @Database + '.sys.sp_ExecuteSQL'
    FROM
        @Databases D;
END

Kommentare zur Erweiterung sind gerne willkommen. ;-)

Anhänge:

  • ****-
    Kommentar von: Christoph Muthmann
    09.12.11 @ 10:13:20

    Hi Frank,
    müßte es nicht c.max_length heißen, damit auch wirklich die Länge der Spalte angezeigt wird?

    Was hältst Du von der Verwendung der information_schemas?

    SELECT
    DB_NAME() as CurrentDatabase,
    O.TABLE_SCHEMA,
    O.TABLE_NAME,
    C.COLUMN_NAME,
    C.ORDINAL_POSITION,
    c.DATA_TYPE,
    c.CHARACTER_MAXIMUM_LENGTH,
    C.NUMERIC_PRECISION,
    C.NUMERIC_SCALE,
    C.is_nullable
    FROM
    information_schema.tables O
    JOIN
    INFORMATION_SCHEMA.columns C ON O.TABLE_CATALOG = C.TABLE_CATALOG and o.TABLE_SCHEMA = c.TABLE_SCHEMA and o.TABLE_NAME = c.TABLE_NAME

    ORDER BY
    O.TABLE_SCHEMA,
    O.TABLE_NAME,
    C.COLUMN_NAME;

  • Kommentar von: Frank Kalis
    12.12.11 @ 08:46:11

    Hi Christoph,
    wahrscheinlich. Die Abfrage habe ich in 1-2 Minuten geschrieben. Den grössten Teil der Zeit hat die Schleife beansprucht.

  • ****-
    Jürgen
    Kommentar von: Jürgen
    22.12.11 @ 09:38:53

    Hi.
    Bin über Dein Statement gestolpert und dacht, das kann man ja immer brauchen ;-)
    Hier noch ein paar kleine Optimierungen (Is_Index, Schema, Comment der Spalte)

    SELECT TOP (100) PERCENT DB_NAME() AS [Database], sys.schemas.name AS [Schema], O.name AS Table_Name, O.modify_date, C.name AS Column_Name,
    C.column_id AS Column_id, P.value AS Column_Comment, S.name AS DataType, C.max_length, C.is_nullable, C.is_identity, C.collation_name,
    CASE WHEN I.index_id > 0 THEN 1 ELSE 0 END AS Column_is_Index
    FROM sys.objects AS O INNER JOIN
    sys.columns AS C ON O.object_id = C.object_id INNER JOIN
    sys.systypes AS S ON C.system_type_id = S.xtype INNER JOIN
    sys.schemas ON O.schema_id = sys.schemas.schema_id LEFT OUTER JOIN
    sys.index_columns AS I ON C.object_id = I.object_id AND C.column_id = I.column_id LEFT OUTER JOIN
    sys.extended_properties AS P ON C.column_id = P.minor_id AND C.object_id = P.major_id
    WHERE (O.type = 'U') AND (O.is_ms_shipped = 0)
    ORDER BY Table_Name, Column_id


    Gruß
    Jürgen

  • Kommentar von: Frank Kalis
    22.12.11 @ 14:06:28

    Hi Jürgen,
    danke! Genau das war die Intention. Es sollte nichts grossartiges sein. Nur für schnelle Ad-Hoc Zwecke, was man halt immer wieder braucht, aber nie findet, wenn man es braucht. :-)
    Ich baue das in den Download zusammen mit Christoph's Vorschlag ein.

Einen Kommentar hinterlassen

Ihre E-Mail-Adresse wird nicht auf dieser Seite angezeigt.
SchlechtExzellent
(Zeilenumbrüche werden zu <br />)
(For my next comment on this site)
(Allow users to contact me through a message form -- Your email will not be revealed!)
Dies ist ein Captcha Bild. Es wird benutzt, um Massenzugriffe von Robotern zu verhindern.
Bitte gib die Zeichen des obigen Bildes ein. (Groß/Kleinschreibung ist wichtig)
Trackback-Adresse für diesen Eintrag
Dies ist ein Captcha Bild. Es wird benutzt, um Massenzugriffe von Robotern zu verhindern.
Bitte gib die Zeichen des obigen Bildes ein. (Groß/Kleinschreibung ist wichtig)