代码之家  ›  专栏  ›  技术社区  ›  Michael Sorens

如何在单个结果集中列出SQL Server中所有数据库中的所有表?

  •  55
  • Michael Sorens  · 技术社区  · 14 年前

    我正在寻找T-SQL代码来列出sqlserver中所有数据库中的所有表(至少在SS2005和SS2008中;很高兴也适用于SS2000)。不过,关键是我想 单一结果集 . 这就排除了其他优秀答案的可能性 Pinal Dave

    sp_msforeachdb 'select "?" AS db, * from [?].sys.tables'
    

    上述存储过程生成一个结果集 WHERE tablename like '%accounts' 然后它会告诉我在哪里可以找到BillAccounts、ClientAccounts和VendorAccounts表,而不管它们位于哪个数据库中。


    到目前为止,雷姆斯的回答看起来最有趣。我没有把它作为一个答案发布给我自己,而是在这里发布了一个我修改过的版本,包括DB名称和一个示例filter子句。看来雷姆斯会得到这个答案,不过,在这一点上!

    declare @sql nvarchar(max);
    set @sql = N'select b.name as "DB", a.name collate Latin1_General_CI_AI as "Table", object_id, schema_id, cast(1 as int) as database_id  from master.sys.tables a join sys.databases b on database_id=1 where a.name like ''account%''';
    
    select @sql = @sql + N' union all select b.name as "DB", a.name collate Latin1_General_CI_AI, object_id, schema_id, ' + cast(database_id as nvarchar(10)) + N' from ' + quotename(name) + N'.sys.tables a join sys.databases b on database_id=' + cast(database_id as nvarchar(10)) + 'where a.name like ''account%'''
    from sys.databases where database_id > 1 
    
    and state = 0
    and user_access = 0;
    
    exec sp_executesql @sql;
    

    2010.05.24更新-新的领跑者!

    反馈和回答都很好。持续的合作参与导致了

    以下是我用雷姆斯的解决方案发现的问题:

    主要问题: 过滤(即省略 WHERE 子句)我在几个我无权访问的数据库上收到此错误:

    服务器主体“msorens”无法访问数据库 当前安全上下文下的“ETLprocDB”。

    查询 使用一些筛选子句成功—那些在我的访问级别之外不接触DBs的子句。

    不容易降级到SQLServer2000支持(是的,我们中的一些人仍然在使用它…),因为它在为每个数据库积累条目的同时构建单个字符串。在我的系统中,我在大约40个数据库中超过了8000个字符。

    次要问题: 重复代码——循环设置实质上复制了循环体。我理解这个道理,但这只是我的一个恼怒。。。

    KM的答案并不受这些问题的影响。存储过程 sp_msforeachdb 考虑用户的权限,以避免权限问题。我还没有尝试过SS2000的代码,但是KM指出了应该做的调整。

    • 我已经删除了服务器名,因为它实际上没有在结果集中添加任何内容。
    • 我为这三个字段中的每一个引入了单独的过滤器。

    下面是我对KM代码的修改(只对表名应用了一个示例过滤器):

    SET NOCOUNT ON
    DECLARE @AllTables table (DbName sysname,SchemaName sysname, TableName sysname)
    DECLARE
         @SearchDb nvarchar(200)
        ,@SearchSchema nvarchar(200)
        ,@SearchTable nvarchar(200)
        ,@SQL nvarchar(4000)
    SET @SearchDb='%'
    SET @SearchSchema='%'
    SET @SearchTable='%Account%'
    SET @SQL='select ''?'' as DbName, s.name as SchemaName, t.name as TableName from [?].sys.tables t inner join sys.schemas s on t.schema_id=s.schema_id WHERE ''?'' LIKE '''+@SearchDb+''' AND s.name LIKE '''+@SearchSchema+''' AND t.name LIKE '''+@SearchTable+''''
    
    INSERT INTO @AllTables (DbName, SchemaName, TableName)
        EXEC sp_msforeachdb @SQL
    SET NOCOUNT OFF
    SELECT * FROM @AllTables ORDER BY DbName, SchemaName, TableName
    
    15 回复  |  直到 14 年前
        1
  •  39
  •   KM.    14 年前

    要获得服务器上所有表的简单方法,请尝试以下操作:

    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
    

    它将返回一个包含服务器+数据库+架构+表名的列: 样本输出:

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

    DECLARE @AllTables table 具有 CREATE TABLE #AllTables 然后每天 @AllTables #AllTables 它会起作用的。

    编辑

    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
    

    将所有表的@Search设置为NULL,将其设置为“dbo.users”或“users”或“.master.dbo”,甚至包括“.master.%.u”等通配符。

        2
  •  14
  •   Remus Rusanu    14 年前
    declare @sql nvarchar(max);
    set @sql = N'select cast(''master'' as sysname) as db_name, name collate Latin1_General_CI_AI, object_id, schema_id, cast(1 as int) as database_id  from master.sys.tables ';
    
    select @sql = @sql + N' union all select ' + quotename(name,'''')+ ', name collate Latin1_General_CI_AI, object_id, schema_id, ' + cast(database_id as nvarchar(10)) + N' from ' + quotename(name) + N'.sys.tables'
    from sys.databases where database_id > 1
    and state = 0
    and user_access = 0;
    
    exec sp_executesql @sql;
    
        3
  •  9
  •   John    7 年前

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

    SET NOCOUNT ON
    DECLARE @AllTables TABLE
            (
             ServerName NVARCHAR(200)
            ,DBName NVARCHAR(200)
            ,SchemaName NVARCHAR(200)
            ,TableName NVARCHAR(200)
            )
    DECLARE @SearchSvr NVARCHAR(200)
           ,@SearchDB NVARCHAR(200)
           ,@SearchS NVARCHAR(200)
           ,@SearchTbl NVARCHAR(200)
           ,@SQL NVARCHAR(4000)
    
    SET @SearchSvr = NULL  --Search for Servers, NULL for all Servers
    SET @SearchDB = NULL  --Search for DB, NULL for all Databases
    SET @SearchS = NULL  --Search for Schemas, NULL for all Schemas
    SET @SearchTbl = NULL  --Search for Tables, NULL for all Tables
    
    SET @SQL = 'SELECT @@SERVERNAME
            ,''?''
            ,s.name
            ,t.name
             FROM [?].sys.tables t 
             JOIN sys.schemas s on t.schema_id=s.schema_id 
             WHERE @@SERVERNAME LIKE ''%' + ISNULL(@SearchSvr, '') + '%''
             AND ''?'' LIKE ''%' + ISNULL(@SearchDB, '') + '%''
             AND s.name LIKE ''%' + ISNULL(@SearchS, '') + '%''
             AND t.name LIKE ''%' + ISNULL(@SearchTbl, '') + '%''
          -- AND ''?'' NOT IN (''master'',''model'',''msdb'',''tempdb'',''SSISDB'')
               '
    -- Remove the '--' from the last statement in the WHERE clause to exclude system tables
    
    INSERT  INTO @AllTables
            (
             ServerName
            ,DBName
            ,SchemaName
            ,TableName
            )
            EXEC sp_MSforeachdb @SQL
    SET NOCOUNT OFF
    SELECT  *
    FROM    @AllTables
    ORDER BY 1,2,3,4
    
        4
  •  3
  •   burakyilmaz321    7 年前

    SELECT * FROM INFORMATION_SCHEMA.TABLES 对于每个数据库,使用 sp_MSforeachdb

    我在VS代码中创建了一个片段,我认为它可能会有所帮助。

    查询

    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 
    

    代码段

    {
        "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"
            ]
        }
    }
    
        5
  •  2
  •   Community kgiannakakis    7 年前

    here 你可以用在这里。大纲是:

    • 创建临时表
    • 对每个DB运行的查询将数据存储在temp表中
    • 完成后,查询temp表
        6
  •  2
  •   dsz    7 年前

    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
    
        7
  •  1
  •   j2associates    7 年前

    我意识到这是一个非常古老的线程,但是当我不得不为承载不同版本的sqlserver的几个不同服务器整理一些系统文档时,它非常有用。为了社区的利益,我创建了4个存储过程。我们使用Dynamics NAV,因此名称中包含NAV的两个存储过程将NAV公司从表名中分离出来。享受。。。

    第4页,共4页-ListServerDatabaseNavTables-用于Dynamics导航

    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
    
        8
  •  0
  •   Joe Phillips    14 年前

    我很确定您必须循环浏览数据库列表,然后列出每个表。你应该能把它们结合在一起。

        9
  •  0
  •   Icemanind    14 年前

    您只需运行sp\u tables存储过程。 http://msdn.microsoft.com/en-us/library/aa260318(SQL.80).aspx

        10
  •  0
  •   the Ben B    7 年前

    这真的很方便,但是我想要一种显示所有用户对象的方法,而不仅仅是表,所以我将它改为使用sys.objects而不是sys.tables

    SET NOCOUNT ON
    DECLARE @AllTables table (DbName sysname,SchemaName sysname, ObjectType char(2), ObjectName sysname)
    DECLARE
         @SearchDb nvarchar(200)
        ,@SearchSchema nvarchar(200)
        ,@SearchObject nvarchar(200)
        ,@SQL nvarchar(4000)
    SET @SearchDb='%'
    SET @SearchSchema='%'
    SET @SearchObject='%Something%'
    SET @SQL='select ''?'' as DbName, s.name as SchemaName, t.type as ObjectType, t.name as ObjectName 
    from [?].sys.objects t inner join sys.schemas s on t.schema_id=s.schema_id 
    WHERE t.type in (''FN'',''IF'',''U'',''V'',''P'',''TF'') 
    AND ''?'' LIKE '''+@SearchDb+''' 
    AND s.name LIKE '''+@SearchSchema+''' 
    AND t.name LIKE '''+@SearchObject+''''
    
    INSERT INTO @AllTables (DbName, SchemaName, ObjectType, ObjectName)
        EXEC sp_msforeachdb @SQL
    SET NOCOUNT OFF
    SELECT * FROM @AllTables ORDER BY DbName, SchemaName, ObjectType, ObjectName
    
        11
  •  0
  •   j2associates    7 年前

    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
    
        12
  •  0
  •   j2associates    7 年前

    我意识到这是一个非常古老的线程,但是当我不得不为承载不同版本的sqlserver的几个不同服务器整理一些系统文档时,它非常有用。为了社区的利益,我创建了4个存储过程。我们使用Dynamics NAV,因此名称中包含NAV的两个存储过程将NAV公司从表名中分离出来。享受。。。

    第2页,共4页-ListServerDatabaseTables

    USE [YourDatabase]
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    ALTER PROC [dbo].[ListServerDatabaseTables]
    (
        @SearchDatabases varchar(max) = NULL,  
        @SearchSchema sysname = 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 
    *       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_DatabaseName sysname
    
        DECLARE @l_Index int
    
        DECLARE @l_UseAndText bit = 0
    
        DECLARE @AllTables table (ServerName sysname, DbName sysname, SchemaName sysname, TableName sysname)
    
        SET @Sql = 
            'select @@ServerName as ''ServerName'', ''?'' as ''DbName'', s.name as ''SchemaName'', t.name as ''TableName'' ' + 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 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, SchemaName COLLATE Latin1_General_CI_AS, TableName COLLATE Latin1_General_CI_AS
    END
    
        13
  •  0
  •   j2associates    7 年前

    我意识到这是一个非常古老的线程,但是当我不得不为承载不同版本的sqlserver的几个不同服务器整理一些系统文档时,它非常有用。为了社区的利益,我创建了4个存储过程。我们使用Dynamics NAV,因此名称中包含NAV的两个存储过程将NAV公司从表名中分离出来。享受。。。

    4个中的3个-ListServerDatabaseNavCompanies-用于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
    
        14
  •  0
  •   Ali Rasouli    6 年前

    请填写搜索表的@likeTablename参数。

    现在将此参数设置为%tbltrans%以搜索名称中包含tbltrans的所有表。

    将@likeTablename设置为“%”以显示所有表。

    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
    
        15
  •  0
  •   Mark    5 年前

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

    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);
    
        16
  •  -1
  •   Bloggins    6 年前

    下面的教程提供了一个T-SQL脚本,该脚本将为位于SQL Server实例中的每个数据库中的每个表返回以下字段:

    1. 方案名称
    2. 表名
    3. 键类型

    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;