How do I list all tables in all databases in SQL Server in a single result set?

后端 未结 16 1228
轮回少年
轮回少年 2020-11-28 07:36

I am looking for T-SQL code to list all tables in all databases in SQL Server (at least in SS2005 and SS2008; would be nice to also apply to SS2000). The catch, however, is

16条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-28 07:48

    Here's a tutorial providing a T-SQL script that will return the following fields for each table from each database located in a SQL Server Instance:

    1. ServerName
    2. DatabaseName
    3. SchemaName
    4. TableName
    5. ColumnName
    6. KeyType

    https://tidbytez.com/2015/06/01/map-the-table-structure-of-a-sql-server-database/

    /*
    SCRIPT UPDATED
    20180316
    */
    
    USE [master]
    GO
    
    /*DROP TEMP TABLES IF THEY EXIST*/
    IF OBJECT_ID('tempdb..#DatabaseList') IS NOT NULL
        DROP TABLE #DatabaseList;
    
    IF OBJECT_ID('tempdb..#TableStructure') IS NOT NULL
        DROP TABLE #TableStructure;
    
    IF OBJECT_ID('tempdb..#ErrorTable') IS NOT NULL
        DROP TABLE #ErrorTable;
    
    IF OBJECT_ID('tempdb..#MappedServer') IS NOT NULL
        DROP TABLE #MappedServer;
    
    DECLARE @ServerName AS SYSNAME
    
    SET @ServerName = @@SERVERNAME
    
    CREATE TABLE #DatabaseList (
        Id INT NOT NULL IDENTITY(1, 1) PRIMARY KEY
        ,ServerName SYSNAME
        ,DbName SYSNAME
        );
    
    CREATE TABLE [#TableStructure] (
        [DbName] SYSNAME
        ,[SchemaName] SYSNAME
        ,[TableName] SYSNAME
        ,[ColumnName] SYSNAME
        ,[KeyType] CHAR(7)
        ) ON [PRIMARY];
    
    /*THE ERROR TABLE WILL STORE THE DYNAMIC SQL THAT DID NOT WORK*/
    CREATE TABLE [#ErrorTable] ([SqlCommand] VARCHAR(MAX)) ON [PRIMARY];
    
    /*
    A LIST OF DISTINCT DATABASE NAMES IS CREATED
    THESE TWO COLUMNS ARE STORED IN THE #DatabaseList TEMP TABLE
    THIS TABLE IS USED IN A FOR LOOP TO GET EACH DATABASE NAME
    */
    INSERT INTO #DatabaseList (
        ServerName
        ,DbName
        )
    SELECT @ServerName
        ,NAME AS DbName
    FROM master.dbo.sysdatabases WITH (NOLOCK)
    WHERE NAME <> 'tempdb'
    ORDER BY NAME ASC
    
    /*VARIABLES ARE DECLARED FOR USE IN THE FOLLOWING FOR LOOP*/
    DECLARE @sqlCommand AS VARCHAR(MAX)
    DECLARE @DbName AS SYSNAME
    DECLARE @i AS INT
    DECLARE @z AS INT
    
    SET @i = 1
    SET @z = (
            SELECT COUNT(*) + 1
            FROM #DatabaseList
            )
    
    /*WHILE 1 IS LESS THAN THE NUMBER OF DATABASE NAMES IN #DatabaseList*/
    WHILE @i < @z
    BEGIN
        /*GET NEW DATABASE NAME*/
        SET @DbName = (
                SELECT [DbName]
                FROM #DatabaseList
                WHERE Id = @i
                )
        /*CREATE DYNAMIC SQL TO GET EACH TABLE NAME AND COLUMN NAME FROM EACH DATABASE*/
        SET @sqlCommand = 'USE [' + @DbName + '];' + '
    
    INSERT INTO [#TableStructure]
    SELECT DISTINCT' + '''' + @DbName + '''' + ' AS DbName
        ,SCHEMA_NAME(SCHEMA_ID) AS SchemaName
        ,T.NAME AS TableName    
        ,C.NAME AS ColumnName
        ,CASE 
            WHEN OBJECTPROPERTY(OBJECT_ID(iskcu.CONSTRAINT_NAME), ''IsPrimaryKey'') = 1 
                THEN ''Primary'' 
            WHEN OBJECTPROPERTY(OBJECT_ID(iskcu.CONSTRAINT_NAME), ''IsForeignKey'') = 1 
                THEN ''Foreign''
            ELSE NULL 
            END AS ''KeyType''
    FROM SYS.TABLES AS t WITH (NOLOCK)
    INNER JOIN SYS.COLUMNS C ON T.OBJECT_ID = C.OBJECT_ID
    LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS iskcu WITH (NOLOCK) 
    ON SCHEMA_NAME(SCHEMA_ID) = iskcu.TABLE_SCHEMA 
        AND T.NAME = iskcu.TABLE_NAME
        AND C.NAME = iskcu.COLUMN_NAME
    ORDER BY SchemaName ASC
        ,TableName ASC
        ,ColumnName ASC;
    ';
    
        /*ERROR HANDLING*/
        BEGIN TRY
            EXEC (@sqlCommand)
        END TRY
    
        BEGIN CATCH
            INSERT INTO #ErrorTable
            SELECT (@sqlCommand)
        END CATCH
    
        SET @i = @i + 1
    END
    
    /*
    JOIN THE TEMP TABLES TOGETHER TO CREATE A MAPPED STRUCTURE OF THE SERVER
    ADDITIONAL FIELDS ARE ADDED TO MAKE SELECTING TABLES AND FIELDS EASIER
    */
    SELECT DISTINCT @@SERVERNAME AS ServerName
        ,DL.DbName
        ,TS.SchemaName
        ,TS.TableName
        ,TS.ColumnName
        ,TS.[KeyType]
        ,',' + QUOTENAME(TS.ColumnName) AS BracketedColumn
        ,',' + QUOTENAME(TS.TableName) + '.' + QUOTENAME(TS.ColumnName) AS BracketedTableAndColumn
        ,'SELECT * FROM ' + QUOTENAME(DL.DbName) + '.' + QUOTENAME(TS.SchemaName) + '.' + QUOTENAME(TS.TableName) + '--WHERE --GROUP BY --HAVING --ORDER BY' AS [SelectTable]
        ,'SELECT ' + QUOTENAME(TS.TableName) + '.' + QUOTENAME(TS.ColumnName) + ' FROM ' + QUOTENAME(DL.DbName) + '.' + QUOTENAME(TS.SchemaName) + '.' + QUOTENAME(TS.TableName) + '--WHERE --GROUP BY --HAVING --ORDER BY' AS [SelectColumn]
    INTO #MappedServer
    FROM [#DatabaseList] AS DL
    INNER JOIN [#TableStructure] AS TS ON DL.DbName = TS.DbName
    ORDER BY DL.DbName ASC
        ,TS.SchemaName ASC
        ,TS.TableName ASC
        ,TS.ColumnName ASC
    
    /*
    HOUSE KEEPING
    */
    IF OBJECT_ID('tempdb..#DatabaseList') IS NOT NULL
        DROP TABLE #DatabaseList;
    
    IF OBJECT_ID('tempdb..#TableStructure') IS NOT NULL
        DROP TABLE #TableStructure;
    
    SELECT *
    FROM #ErrorTable;
    
    IF OBJECT_ID('tempdb..#ErrorTable') IS NOT NULL
        DROP TABLE #ErrorTable;
    
    /*
    THE DATA RETURNED CAN NOW BE EXPORTED TO EXCEL
    USING A FILTERED SEARCH WILL NOW MAKE FINDING FIELDS A VERY EASY PROCESS
    */
    SELECT ServerName
        ,DbName
        ,SchemaName
        ,TableName
        ,ColumnName
        ,KeyType
        ,BracketedColumn
        ,BracketedTableAndColumn
        ,SelectColumn
        ,SelectTable
    FROM #MappedServer
    ORDER BY DbName ASC
        ,SchemaName ASC
        ,TableName ASC
        ,ColumnName ASC;
    

提交回复
热议问题