使用SQL Server系统目录中的元数据关联数据库名称

时间:2017-10-04 13:21:54

标签: sql sql-server

我想生成一个报告,显示有关服务器上数据库的表和列的元数据。

理想情况下,我希望将数据库本身作为报表中的列包含在内,但无法在sys上的各个SQL Server对象之间找到合适的关系。

到目前为止,我有:

  

DECLARE @R VARCHAR(50)

     

SET @R ='Test1'

     

DECLARE @T VARCHAR(50)

     

SET @T ='TESTSTUFF'

     

SELECT AC。[name] AS [COLUMN_NAME],T。[name] AS [TABLE_NAME],@ R AS [DATABASE],'AS [DESCRIPTION]

     

FROM Test1.sys。[tables] AS T

     

INNER JOIN Test1.sys。[all_columns] AC ON T. [object_id] = AC。[object_id]`

     

WHERE T. [is_ms_shipped] = 0

     

UNION ALL

     

SELECT AC。[name] AS [column_name],           T. [name] AS [table_name],@ T AS [DATABASE],'AS [DESCRIPTION]

     

FROM TESTSTUFF.sys。[tables] AS T

     

INNER JOIN TESTSTUFF.sys。[all_columns] AC ON T. [object_id] = AC。[object_id]

     

WHERE T. [is_ms_shipped] = 0

通过创建数据库名称的参数,我引入了一种我认为不必要的高度可维护性。理想情况下,我希望将其作为一个视图,因为每次添加数据库对象时它都会自动更新。

目标是实现这样的目标:

  

DECLARE @D VARCHAR(50)

     

SET @D =(SELECT NAME FROM sys.databases WHERE name NOT IN('master','tempdb','model','msdb'))

     

SELECT AC。[name] AS [COLUMN_NAME],T。[name] AS [TABLE_NAME],@ D AS [DATABASE],'AS [DESCRIPTION]

     

FROM sys。[tables] AS T
    INNER JOIN sys。[all_columns] AC ON T. [object_id] = AC。[object_id]

     

INNER JOIN sys.databases d ON ?????

     

WHERE T. [is_ms_shipped] = 0

是否可以这样做?

3 个答案:

答案 0 :(得分:1)

虽然您无法使用视图,但您可以使用生成动态SQL语句的脚本或存储过程。下面的示例生成每个数据库的目录视图的UNION ALL查询,每个数据库都使用数据库名称进行限定。

DECLARE @SQL nvarchar(MAX);

SELECT @SQL = STUFF(
    (SELECT 'UNION ALL
    SELECT AC.[name] COLLATE Latin1_General_100_CI_AS_KS_WS_SC AS [COLUMN_NAME], T.[name] COLLATE Latin1_General_100_CI_AS_KS_WS_SC AS [TABLE_NAME], N''' + name + N''' AS [Database], '''' AS [DESCRIPTION]
    FROM ' + QUOTENAME(name) + '.sys.[tables] AS T 
    INNER JOIN ' + QUOTENAME(name) + '.sys.[all_columns] AC ON T.[object_id] = AC.[object_id]
    WHERE T.[is_ms_shipped] = 0 '
    FROM sys.databases
    WHERE name NOT IN ('master', 'tempdb', 'model', 'msdb')
    FOR XML PATH, TYPE).value('.', 'nvarchar(MAX)'),1,11,'') + N';';

EXEC(@SQL);

答案 1 :(得分:0)

如果您使用[INFORMATION_SCHEMA].[COLUMNS]代替sys视图,则会显示[TABLE_CATALOG]列,该列可用于加入sys.databases

答案 2 :(得分:0)

您需要使用

  1. sp_MSforeachdb存储过程以绕过服务器上的所有数据库
  2. 可以使用此t-sql脚本

    建立DB-Table-Schema之间的链接
    SELECT DB_NAME () as DataBaseName,
    s.Name as SchemaName,
    t.NAME as TableName
    FROM  sys.tables t
    JOIN  sys.indexes i ON t.object_id = i.object_id
    JOIN  sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id
    JOIN  sys.allocation_units a ON p.partition_id = a.container_id
    JOIN sys.schemas s ON t.schema_id = s.schema_id 
    WHERE t.is_ms_shipped = 0 and t.NAME NOT LIKE 'dt%' 
    GROUP BY  t.Name, s.Name, p.Rows,t.create_date 
    ORDER BY  DB_NAME(),s.Name,t.Name