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

后端 未结 16 934
轮回少年
轮回少年 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:47

    I posted an answer a while back here that you could use here. The outline is:

    • Create a temp table
    • Call sp_msForEachDb
    • The query run against each DB stores the data in the temp table
    • When done, query the temp table
    0 讨论(0)
  • 2020-11-28 07:47

    please fill the @likeTablename param for search table.

    now this parameter set to %tbltrans% for search all table contain tbltrans in name.

    set @likeTablename to '%' to show all table.

    declare @AllTableNames nvarchar(max);
    
    select  @AllTableNames=STUFF((select ' SELECT  TABLE_CATALOG collate DATABASE_DEFAULT+''.''+TABLE_SCHEMA collate DATABASE_DEFAULT+''.''+TABLE_NAME collate DATABASE_DEFAULT as tablename FROM '+name+'.INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = ''BASE TABLE'' union '
     FROM master.sys.databases 
    FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'');
    
    set @AllTableNames=left(@AllTableNames,len(@AllTableNames)-6)
    
    declare @likeTablename nvarchar(200)='%tbltrans%';
    set @AllTableNames=N'select tablename from('+@AllTableNames+N')at where tablename like '''+N'%'+@likeTablename+N'%'+N''''
    exec sp_executesql  @AllTableNames
    
    0 讨论(0)
  • 2020-11-28 07:48

    Link to a stored-procedure-less approach that Bart Gawrych posted on Dataedo site

    I was asking myself, 'Do we really have to use a stored procedure here?' and I found this helpful post. (The state=0 was added to fix issues with offline databases per feedback from users of the linked page.)

    declare @sql nvarchar(max);
    
    select @sql = 
        (select ' UNION ALL
            SELECT ' +  + quotename(name,'''') + ' as database_name,
                   s.name COLLATE DATABASE_DEFAULT
                        AS schema_name,
                   t.name COLLATE DATABASE_DEFAULT as table_name 
                   FROM '+ quotename(name) + '.sys.tables t
                   JOIN '+ quotename(name) + '.sys.schemas s
                        on s.schema_id = t.schema_id'
        from sys.databases 
        where state=0
        order by [name] for xml path(''), type).value('.', 'nvarchar(max)');
    
    set @sql = stuff(@sql, 1, 12, '') + ' order by database_name, 
                                                   schema_name,
                                                   table_name';
    
    execute (@sql);
    
    0 讨论(0)
  • 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;
    
    0 讨论(0)
  • 2020-11-28 07:52

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

    3 of 4 - ListServerDatabaseNavCompanies - for Dynamics NAV

    USE [YourDatabase]
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER PROC [dbo].[ListServerDatabaseNavCompanies]
    (
        @SearchDatabases varchar(max) = NULL,  
        @SearchSchema sysname = NULL,
        @SearchCompanies varchar(max) = NULL,
        @OrderByDatabaseNameFirst bit = 1, 
        @ExcludeSystemDatabases bit = 1, 
        @Sql varchar(max) OUTPUT
    )
    AS BEGIN
    
    /**************************************************************************************************************************************
    * Lists all of the database companies 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  
    *       OrderByDatabaseNameFirst - 1 to sort by Database name and then Company Name, otherwise 0 to sort by Company name first 
    *                                  Defaults to 1
    *       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_CompanyName sysname
        DECLARE @l_DatabaseName sysname
    
        DECLARE @l_Index int
    
        DECLARE @l_UseAndText bit = 0
    
        DECLARE @l_Companies table (ServerName sysname, DbName sysname, SchemaName sysname, CompanyName sysname)
    
        SET @Sql = 
            'select distinct @@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) +
            '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
    
        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 @l_Companies 
        EXEC sp_msforeachdb @Sql
    
        SELECT CASE WHEN @OrderByDatabaseNameFirst = 1 THEN 'DbName & CompanyName' ELSE 'CompanyName & DbName' END AS 'Sorted by'
        SELECT ServerName, DbName COLLATE Latin1_General_CI_AS AS 'DbName', SchemaName COLLATE Latin1_General_CI_AS AS 'SchemaName', CompanyName COLLATE Latin1_General_CI_AS AS 'CompanyName'
        FROM @l_Companies 
        ORDER BY SchemaName COLLATE Latin1_General_CI_AS,
            CASE WHEN @OrderByDatabaseNameFirst = 1 THEN DbName COLLATE Latin1_General_CI_AS ELSE CompanyName COLLATE Latin1_General_CI_AS END,
            CASE WHEN @OrderByDatabaseNameFirst = 1 THEN CompanyName COLLATE Latin1_General_CI_AS ELSE DbName COLLATE Latin1_General_CI_AS END
    END
    
    0 讨论(0)
  • 2020-11-28 07:53

    All you need to do is run the sp_tables stored procedure. http://msdn.microsoft.com/en-us/library/aa260318(SQL.80).aspx

    0 讨论(0)
提交回复
热议问题