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. ;-)
Trackback-Adresse für diesen Eintrag

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