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

我正在寻找T-SQL代码来列出SQL Server中的所有数据库中的所有表(至less在SS2005和SS2008;将不错,也适用于SS2000)。 但是,我想要一个结果集 。 这排除了Pinal Dave的其他优秀答案:

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

上面存储的proc 为每个数据库生成一个结果集,如果你在像SSMS这样的可以显示多个结果集的IDE中,这是很好的。 然而,我想要一个单一的结果集,因为我想要一个本质上是“查找”工具的查询:如果我添加一个像WHERE tablename like '%accounts'的子句, WHERE tablename like '%accounts'那么它会告诉我在哪里可以find我的BillAccounts,ClientAccounts和VendorAccounts不pipe他们驻留在哪个数据库中。


2010.05.20更新,约20分钟后…

到目前为止,Remus的回答看起来很有趣。 而不是发表这个答案,并奖励给自己,我在这里张贴它的一个版本,我已经修改,包括数据库名称和样本筛选器条款。 看起来Remus会得到这个答案的功劳,尽pipe如此!

 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更新 – 新的领跑者!

反馈和答案一直很好。 持续的合作参与带来了一个新的领跑者 :5月21日KM的回答!

以下是我用Remus的解决scheme发现的问题:

主要问题:用户根据数据(即过滤值)有不同的权限导致查询成功。 在没有过滤的情况下运行我的生产数据库(即省略WHERE子句)我在几个没有权限访问的数据库上收到此错误:

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

该查询成功与一些过滤条款 – 那些不接触我的访问级别以外的数据库。

小问题:不容易降级到SQL Server 2000的支持(是的,我们还有一些人使用它…),因为它build立一个单一的string,同时积累每个数据库的条目。 用我的系统,我在40个数据库上超过了8000个字符。

小问题:重复的代码 – 循环设置本质上复制循环体。 我明白这个理由,但这只是我的宠物

KM的答案不受这些问题的困扰。 存储过程sp_msforeachdb考虑到用户的权限,所以它避免了权限问题。 我还没有尝试SS2000的代码,但KM表明应该做的调整。

我将根据我的个人喜好发表下一篇修改KM的答案。 特别:

  • 我已经删除了服务器名称,因为它不会在结果集中添加任何内容。
  • 我已将名称组件拆分到结果集(数据库名称,模式名称和表名称)中的各自的字段中。
  • 我已经为这三个领域的每一个引入了单独的filter。
  • 我已经添加了三个字段的sorting(可以根据您的喜好进行修改)。

以下是我对KM代码的修改(仅适用于表名的示例filter):

 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 

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

 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 

它将返回一个包含server + database + schema +表名的列:sample output:

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

如果您不在SQL Server 2005或更高版本上,请将DECLARE @AllTables tablereplace为CREATE TABLE #AllTables ,然后将每个@AllTables#AllTables ,它将起作用。

编辑
这是一个允许在服务器+数据库+模式+表名称的任何部分或部分上使用search参数的版本:

 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”之类的通配符。

 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; 

我需要的东西,我可以用来search我所有的服务器使用CMS和search服务器,数据库,架构或表。 这是我发现的(最初由Michael Sorens在这里发布: 如何在单个结果集中的SQL Server中的所有数据库中列出所有表? )。

 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 

我在这里发布了一个答案,你可以在这里使用。 大纲是:

  • 创build一个临时表
  • 调用sp_msForEachDb
  • 对每个DB运行的查询将数据存储在临时表中
  • 完成后,查询临时表

我认为常用的方法是使用sp_MSforeachdb为每个数据库SELECT * FROM INFORMATION_SCHEMA.TABLES

我在VS Code中创build了一个片段,我认为这可能会有所帮助。

询问

 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" ] } } 

我很确定你必须遍历数据库列表,然后列出每个表。 你应该能够把它们结合在一起。

所有你需要做的是运行sp_tables存储过程。 http://msdn.microsoft.com/en-us/library/aa260318(SQL.80).aspx

这真的很方便,但我想要一种方式来显示所有的用户对象,而不仅仅是表,所以我调整它使用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 

我非常喜欢使用INFORMATION_SCHEMA,因为我可以免费获取数据库名称。 这和 – 从@KM发布实现多个结果集插入很好 – 我想出了:

 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 

我意识到这是一个非常老的线程,但是当我必须为托pipe不同版本的Sql Server的几个不同服务器组合一些系统文档时,这非常有帮助。 我最终创build了4个存储过程,这些存储过程是为了社区的利益而发布的。 我们使用dynamic导航,所以名称中的NAV的两个存储过程将Nav公司从表名中分离出来。 请享用…

1 – 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 

我意识到这是一个非常老的线程,但是当我必须为托pipe不同版本的Sql Server的几个不同服务器组织一些系统文档时,这非常有帮助。 我最终创build了4个存储过程,这些存储过程是为了社区的利益而发布的。 我们使用dynamic导航,所以名称中的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 

我意识到这是一个非常老的线程,但是当我必须为托pipe不同版本的Sql Server的几个不同服务器组合一些系统文档时,这非常有帮助。 我最终创build了4个存储过程,这些存储过程是为了社区的利益而发布的。 我们使用dynamic导航,所以名称中的NAV的两个存储过程将Nav公司从表名中分离出来。 请享用…

3/4 – 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 

我意识到这是一个非常老的线程,但是当我必须为托pipe不同版本的Sql Server的几个不同服务器组合一些系统文档时,这非常有帮助。 我最终创build了4个存储过程,这些存储过程是为了社区的利益而发布的。 我们使用dynamic导航,所以名称中的NAV的两个存储过程将Nav公司从表名中分离出来。 请享用…

4/4 – ListServerDatabaseNavTables – 适用于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