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

后端 未结 16 933
轮回少年
轮回少年 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条回答
  • 2020-11-28 07:42

    I realize this is a very old thread, but it was very helpful when I had to put together some system documentation for several different servers that were hosting different versions of Sql Server. I ended up creating 4 stored procedures which I am posting here for the benefit of the community. We use Dynamics NAV so the two stored procedures with NAV in the name split the Nav company out of the table name. Enjoy...

    4 of 4 - ListServerDatabaseNavTables - for Dynamics NAV

    USE [YourDatabase]
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER proc [dbo].[ListServerDatabaseNavTables]
    (
        @SearchDatabases varchar(max) = NULL,  
        @SearchSchema sysname = NULL,
        @SearchCompanies varchar(max) = NULL,
        @SearchTables varchar(max) = NULL,
        @ExcludeSystemDatabases bit = 1,
        @Sql varchar(max) OUTPUT
    )
    AS BEGIN
    
    /**************************************************************************************************************************************
    * Lists all of the database tables for a given server.
    *   Parameters
    *       SearchDatabases - Comma delimited list of database names for which to search - converted into series of Like statements
    *                         Defaults to null  
    *       SearchSchema - Schema name for which to search
    *                      Defaults to null 
    *       SearchCompanies - Comma delimited list of company names for which to search - converted into series of Like statements
    *                         Defaults to null  
    *       SearchTables - Comma delimited list of table names for which to search - converted into series of Like statements
    *                      Defaults to null 
    *       ExcludeSystemDatabases - 1 to exclude system databases, otherwise 0
    *                          Defaults to 1
    *       Sql - Output - the stored proc generated sql
    *
    *   Adapted from answer by KM answered May 21 '10 at 13:33
    *   From: How do I list all tables in all databases in SQL Server in a single result set?
    *   Link: https://stackoverflow.com/questions/2875768/how-do-i-list-all-tables-in-all-databases-in-sql-server-in-a-single-result-set
    *
    **************************************************************************************************************************************/
    
        SET NOCOUNT ON
    
        DECLARE @l_CompoundLikeStatement varchar(max) = ''
        DECLARE @l_TableName sysname
        DECLARE @l_CompanyName sysname
        DECLARE @l_DatabaseName sysname
    
        DECLARE @l_Index int
    
        DECLARE @l_UseAndText bit = 0
    
        DECLARE @AllTables table (ServerName sysname, DbName sysname, SchemaName sysname, CompanyName sysname, TableName sysname, NavTableName sysname)
    
        SET @Sql = 
            'select @@ServerName as ''ServerName'', ''?'' as ''DbName'', s.name as ''SchemaName'', ' + char(13) +
            '       case when charindex(''$'', t.name) = 0 then '''' else left(t.name, charindex(''$'', t.name) - 1) end as ''CompanyName'', ' + char(13) +
            '       case when charindex(''$'', t.name) = 0 then t.name else substring(t.name, charindex(''$'', t.name) + 1, 1000) end as ''TableName'', ' + char(13) +
            '       t.name as ''NavTableName'' ' + char(13) +
            'from [?].sys.tables t inner join ' + char(13) + 
            '     sys.schemas s on t.schema_id = s.schema_id '
    
        -- Comma delimited list of database names for which to search
        IF @SearchDatabases IS NOT NULL BEGIN
            SET @l_CompoundLikeStatement = char(13) + 'where (' + char(13)
            WHILE LEN(LTRIM(RTRIM(@SearchDatabases))) > 0 BEGIN
                SET @l_Index = CHARINDEX(',', @SearchDatabases)
                IF @l_Index = 0 BEGIN
                    SET @l_DatabaseName = LTRIM(RTRIM(@SearchDatabases))
                END ELSE BEGIN
                    SET @l_DatabaseName = LTRIM(RTRIM(LEFT(@SearchDatabases, @l_Index - 1)))
                END
    
                SET @SearchDatabases = LTRIM(RTRIM(REPLACE(LTRIM(RTRIM(REPLACE(@SearchDatabases, @l_DatabaseName, ''))), ',', '')))
                SET @l_CompoundLikeStatement = @l_CompoundLikeStatement + char(13) + ' ''?'' like ''' + @l_DatabaseName + '%'' COLLATE Latin1_General_CI_AS or '
            END
    
            -- Trim trailing Or and add closing right parenthesis )
            SET @l_CompoundLikeStatement = LTRIM(RTRIM(@l_CompoundLikeStatement))
            SET @l_CompoundLikeStatement = LEFT(@l_CompoundLikeStatement, LEN(@l_CompoundLikeStatement) - 2) + ')'
    
            SET @Sql = @Sql + char(13) +
                @l_CompoundLikeStatement
    
            SET @l_UseAndText = 1
        END
    
        -- Search schema
        IF @SearchSchema IS NOT NULL BEGIN
            SET @Sql = @Sql + char(13)
            SET @Sql = @Sql + CASE WHEN @l_UseAndText = 1 THEN '  and ' ELSE 'where ' END +
                's.name LIKE ''' + @SearchSchema + ''' COLLATE Latin1_General_CI_AS'
            SET @l_UseAndText = 1
        END
    
        -- Comma delimited list of company names for which to search
        IF @SearchCompanies IS NOT NULL BEGIN
            SET @l_CompoundLikeStatement = char(13) + CASE WHEN @l_UseAndText = 1 THEN '  and (' ELSE 'where (' END + char(13) 
            WHILE LEN(LTRIM(RTRIM(@SearchCompanies))) > 0 BEGIN
                SET @l_Index = CHARINDEX(',', @SearchCompanies)
                IF @l_Index = 0 BEGIN
                    SET @l_CompanyName = LTRIM(RTRIM(@SearchCompanies))
                END ELSE BEGIN
                    SET @l_CompanyName = LTRIM(RTRIM(LEFT(@SearchCompanies, @l_Index - 1)))
                END
    
                SET @SearchCompanies = LTRIM(RTRIM(REPLACE(LTRIM(RTRIM(REPLACE(@SearchCompanies, @l_CompanyName, ''))), ',', '')))
                SET @l_CompoundLikeStatement = @l_CompoundLikeStatement + char(13) + ' t.name like ''' + @l_CompanyName + '%'' COLLATE Latin1_General_CI_AS or '
            END
    
            -- Trim trailing Or and add closing right parenthesis )
            SET @l_CompoundLikeStatement = LTRIM(RTRIM(@l_CompoundLikeStatement))
            SET @l_CompoundLikeStatement = LEFT(@l_CompoundLikeStatement, LEN(@l_CompoundLikeStatement) - 2) + ' )'
    
            SET @Sql = @Sql + char(13) +
                @l_CompoundLikeStatement
    
            SET @l_UseAndText = 1
        END
    
        -- Comma delimited list of table names for which to search
        IF @SearchTables IS NOT NULL BEGIN
            SET @l_CompoundLikeStatement = char(13) + CASE WHEN @l_UseAndText = 1 THEN '  and (' ELSE 'where (' END + char(13) 
            WHILE LEN(LTRIM(RTRIM(@SearchTables))) > 0 BEGIN
                SET @l_Index = CHARINDEX(',', @SearchTables)
                IF @l_Index = 0 BEGIN
                    SET @l_TableName = LTRIM(RTRIM(@SearchTables))
                END ELSE BEGIN
                    SET @l_TableName = LTRIM(RTRIM(LEFT(@SearchTables, @l_Index - 1)))
                END
    
                SET @SearchTables = LTRIM(RTRIM(REPLACE(LTRIM(RTRIM(REPLACE(@SearchTables, @l_TableName, ''))), ',', '')))
                SET @l_CompoundLikeStatement = @l_CompoundLikeStatement + char(13) + ' t.name like ''$' + @l_TableName + ''' COLLATE Latin1_General_CI_AS or '
            END
    
            -- Trim trailing Or and add closing right parenthesis )
            SET @l_CompoundLikeStatement = LTRIM(RTRIM(@l_CompoundLikeStatement))
            SET @l_CompoundLikeStatement = LEFT(@l_CompoundLikeStatement, LEN(@l_CompoundLikeStatement) - 2) + ' )'
    
            SET @Sql = @Sql + char(13) +
                @l_CompoundLikeStatement
    
            SET @l_UseAndText = 1
        END
    
        IF @ExcludeSystemDatabases = 1 BEGIN
            SET @Sql = @Sql + char(13)
            SET @Sql = @Sql + case when @l_UseAndText = 1 THEN '  and ' ELSE 'where ' END +
                '''?'' not in (''master'' COLLATE Latin1_General_CI_AS, ''model'' COLLATE Latin1_General_CI_AS, ''msdb'' COLLATE Latin1_General_CI_AS, ''tempdb'' COLLATE Latin1_General_CI_AS)' 
        END
    
    /*  PRINT @Sql  */
    
        INSERT INTO @AllTables 
        EXEC sp_msforeachdb @Sql
    
        SELECT * FROM @AllTables ORDER BY DbName COLLATE Latin1_General_CI_AS, CompanyName COLLATE Latin1_General_CI_AS, TableName COLLATE Latin1_General_CI_AS
    END
    
    0 讨论(0)
  • 2020-11-28 07:43

    I'm pretty sure you'll have to loop through the list of databases and then list each table. You should be able to union them together.

    0 讨论(0)
  • 2020-11-28 07:43

    I realize this is a very old thread, but it was very helpful when I had to put together some system documentation for several different servers that were hosting different versions of Sql Server. I ended up creating 4 stored procedures which I am posting here for the benefit of the community. We use Dynamics NAV so the two stored procedures with NAV in the name split the Nav company out of the table name. Enjoy...

    1 of 4 - ListServerDatabases

    USE [YourDatabase]
    GO
    
    /****** Object:  StoredProcedure [pssi].[ListServerDatabases]    Script Date: 10/3/2017 8:56:45 AM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER PROC [dbo].[ListServerDatabases]
    (
        @SearchDatabases varchar(max) = NULL,  
        @ExcludeSystemDatabases bit = 1,
        @Sql varchar(max) OUTPUT
    )
    AS BEGIN
    
    /**************************************************************************************************************************************
    * Lists all of the databases for a given server.
    *   Parameters
    *       SearchDatabases - Comma delimited list of database names for which to search - converted into series of Like statements
    *                         Defaults to null  
    *       ExcludeSystemDatabases - 1 to exclude system databases, otherwise 0
    *                                Defaults to 1
    *       Sql - Output - the stored proc generated sql
    *
    *   Adapted from answer by 
    *   From: How do I list all tables in all databases in SQL Server in a single result set?
    *   Link: https://stackoverflow.com/questions/2875768/how-do-i-list-all-tables-in-all-databases-in-sql-server-in-a-single-result-set
    *
    **************************************************************************************************************************************/
    
        SET NOCOUNT ON
    
        DECLARE @l_CompoundLikeStatement varchar(max) = ''
        DECLARE @l_DatabaseName sysname
    
        DECLARE @l_Index int
    
        DECLARE @lUseAndText bit = 0
    
        DECLARE @l_AllDatabases table (ServerName sysname, DbName sysname)
    
        SET @Sql = 
            'select @@ServerName as ''ServerName'', ''?'' as ''DbName'''
    
        IF @SearchDatabases IS NOT NULL BEGIN
            SET @l_CompoundLikeStatement = char(13) + 'where (' + char(13)
            WHILE LEN(LTRIM(RTRIM(@SearchDatabases))) > 0 BEGIN
                SET @l_Index = CHARINDEX(',', @SearchDatabases)
                IF @l_Index = 0 BEGIN
                    SET @l_DatabaseName = LTRIM(RTRIM(@SearchDatabases))
                END ELSE BEGIN
                    SET @l_DatabaseName = LTRIM(RTRIM(LEFT(@SearchDatabases, @l_Index - 1)))
                END
    
                SET @SearchDatabases = LTRIM(RTRIM(REPLACE(LTRIM(RTRIM(REPLACE(@SearchDatabases, @l_DatabaseName, ''))), ',', '')))
                SET @l_CompoundLikeStatement = @l_CompoundLikeStatement + char(13) + ' ''?'' like ''' + @l_DatabaseName + '%'' COLLATE Latin1_General_CI_AS or '
            END
    
            -- Trim trailing Or and add closing right parenthesis )
            SET @l_CompoundLikeStatement = LTRIM(RTRIM(@l_CompoundLikeStatement))
            SET @l_CompoundLikeStatement = LEFT(@l_CompoundLikeStatement, LEN(@l_CompoundLikeStatement) - 2) + ' )'
    
            SET @Sql = @Sql + char(13) +
                @l_CompoundLikeStatement
    
            SET @lUseAndText = 1
        END
    
        IF @ExcludeSystemDatabases = 1 BEGIN
            SET @Sql = @Sql + char(13)
            SET @Sql = @Sql + case when @lUseAndText = 1 THEN '  and ' ELSE 'where ' END +
                '''?'' not in (''master'' COLLATE Latin1_General_CI_AS, ''model'' COLLATE Latin1_General_CI_AS, ''msdb'' COLLATE Latin1_General_CI_AS, ''tempdb'' COLLATE Latin1_General_CI_AS)' 
        END
    
    /*  PRINT @Sql  */
    
        INSERT INTO @l_AllDatabases 
        EXEC sp_msforeachdb @Sql
    
        SELECT * FROM @l_AllDatabases ORDER BY DbName
    END
    
    0 讨论(0)
  • 2020-11-28 07:44

    I think the common approach is to SELECT * FROM INFORMATION_SCHEMA.TABLES for each database using sp_MSforeachdb

    I created a snippet in VS Code that I think it might be helpful.

    Query

    IF OBJECT_ID('tempdb..#alltables', 'U') IS NOT NULL DROP TABLE #alltables;
    SELECT * INTO #alltables FROM INFORMATION_SCHEMA.TABLES;
    TRUNCATE TABLE #alltables;
    EXEC sp_MSforeachdb 'USE [?];INSERT INTO #alltables SELECT * from INFORMATION_SCHEMA.TABLES';
    SELECT * FROM #alltables WHERE TABLE_NAME LIKE '%<TABLE_NAME_TO_SEARCH>%';
    GO 
    

    Snippet

    {
        "List all tables": {
            "prefix": "sqlListTable",
            "body": [
                "IF OBJECT_ID('tempdb..#alltables', 'U') IS NOT NULL DROP TABLE #alltables;",
                "SELECT * INTO #alltables FROM INFORMATION_SCHEMA.TABLES;",
                "TRUNCATE TABLE #alltables;",
                "EXEC sp_MSforeachdb 'USE [?];INSERT INTO #alltables SELECT * from INFORMATION_SCHEMA.TABLES';",
                "SELECT * FROM #alltables WHERE TABLE_NAME LIKE '%$0%';",
                "GO"
            ]
        }
    }
    
    0 讨论(0)
  • 2020-11-28 07:45

    for a simple way to get all tables on the server, try this:

    SET NOCOUNT ON
    DECLARE @AllTables table (CompleteTableName nvarchar(4000))
    INSERT INTO @AllTables (CompleteTableName)
        EXEC sp_msforeachdb 'select @@SERVERNAME+''.''+''?''+''.''+s.name+''.''+t.name from [?].sys.tables t inner join sys.schemas s on t.schema_id=s.schema_id'
    SET NOCOUNT OFF
    SELECT * FROM @AllTables ORDER BY 1
    

    it will return a single column that contains the server+database+schema+table name: sample output:

    CompleteTableName
    --------------------------------------------
    YourServer.YourDatabase1.YourSchema1.YourTable1
    YourServer.YourDatabase1.YourSchema1.YourTable2
    YourServer.YourDatabase1.YourSchema2.YourTable1
    YourServer.YourDatabase1.YourSchema2.YourTable2
    YourServer.YourDatabase2.YourSchema1.YourTable1
    

    if you are not on SQL Server 2005 or up, replace the DECLARE @AllTables table with CREATE TABLE #AllTables and then every @AllTables with #AllTables and it will work.

    EDIT
    here is a version that will allow a search parameter to be used on any part or parts of the server+database+schema+table names:

    SET NOCOUNT ON
    DECLARE @AllTables table (CompleteTableName nvarchar(4000))
    DECLARE @Search nvarchar(4000)
           ,@SQL   nvarchar(4000)
    SET @Search=null --all rows
    SET @SQL='select @@SERVERNAME+''.''+''?''+''.''+s.name+''.''+t.name from [?].sys.tables t inner join sys.schemas s on t.schema_id=s.schema_id WHERE @@SERVERNAME+''.''+''?''+''.''+s.name+''.''+t.name LIKE ''%'+ISNULL(@SEARCH,'')+'%'''
    
    INSERT INTO @AllTables (CompleteTableName)
        EXEC sp_msforeachdb @SQL
    SET NOCOUNT OFF
    SELECT * FROM @AllTables ORDER BY 1
    

    set @Search to NULL for all tables, set it to things like 'dbo.users' or 'users' or '.master.dbo' or even include wildcards like '.master.%.u', etc.

    0 讨论(0)
  • 2020-11-28 07:45

    I quite like using INFORMATION_SCHEMA for this as I get the DB name for free. That and - realising from @KM post that multiple results sets insert nicely - I came up with:

    select top 0 * 
        into #temp
        from INFORMATION_SCHEMA.TABLES
    
    insert into #temp
        exec sp_msforeachdb 'select * from [?].INFORMATION_SCHEMA.TABLES'
    
    select * from #temp
    
    drop table #temp
    
    0 讨论(0)
提交回复
热议问题