Quick and Dirty Datenbank Dokumentierer

By Frank Kalis

Posted on Dez 9, 2011 von in SQL Server

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:

Tags: Tags: ,
Dieser Eintrag wurde eingetragen von und ist abgelegt unter SQL Server. Tags: ,
Tags: ,

4 Kommentare

Benutzerwertungen
5 Stern:
 
(0)
4 Stern:
 
(2)
3 Stern:
 
(0)
2 Stern:
 
(0)
1 Stern:
 
(0)
2 Bewertungen
Durschn. Benutzerwertung:
(4.0)
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;
09.12.11 @ 10:13
Hi Christoph, wahrscheinlich. Die Abfrage habe ich in 1-2 Minuten geschrieben. Den grössten Teil der Zeit hat die Schleife beansprucht.
12.12.11 @ 08:46

Kommentar von: Jürgen

Jürgen
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
22.12.11 @ 09:38
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.
22.12.11 @ 14:06


Formular wird geladen...