列出服务器上包含模式的所有表是没有问题的
SELECT SCHEMA_NAME(schema_id), name FROM sys.tables
如何确定表所在的数据库?
答案 0 :(得分:8)
sys.tables存在于所有数据库中,因此我没有关注您不知道您所在的数据库的事实。您可以运行DB_NAME(DB_ID())来获取数据库名称
SELECT DB_NAME(DB_ID()),SCHEMA_NAME(schema_id), name FROM sys.tables
但在这种情况下,DB_NAME(DB_ID())将为每一行返回相同的值
为所有数据库执行此操作,您可以执行此操作
EXEC sp_msforeachdb 'use [?] SELECT ''?'',SCHEMA_NAME(schema_id), name
FROM sys.tables'
您当然可以将其转储到表格中
CREATE TABLE #output (DatabaseName VARCHAR(1000),
SchemaName VARCHAR(1000),
TableName VARCHAR(1000))
INSERT #output
EXEC sp_msforeachdb 'use [?] SELECT ''?'',SCHEMA_NAME(schema_id), name
FROM sys.tables'
SELECT * FROM #output
就像一个FYI,sp_msforeachdb proc没有文档,你不应该将它用于生产代码,快速找到一些好的东西,因为生产代码滚动你自己的proc版本
另见Aaron Bertrand的帖子:
答案 1 :(得分:3)
我在创建查询时遇到了这个问题,我希望能够针对服务器上的其他数据库运行,并包含其他数据库的名称,而不将其硬编码到查询中。
查询基本上如下所示:
SELECT DB_NAME() db_name
, SCHEMA_NAME(schema_id) schema_name
, name table_name
FROM OtherDB.sys.tables --The OtherDB is to specify that I am running
--this for a different database than the one
--I'm logged in to for my current session.
问题在于,即使我在from子句中指定OtherDB.sys.tables
,DB_NAME()
也总是返回我当前所在的数据库。是的,我可以在开头放一个USE OtherDB
,但似乎应该有另一种方式。我查看了我能找到的每个系统视图,但却找不到任何可以链接sys.databases
和sys.tables
的视图。
我最终找到的是SQL Server INFORMATION_SCHEMA.TABLES
此视图包含数据库名称作为第一列(称为TABLE_CATAOLG
)。
SELECT TABLE_CATALOG
, TABLE_SCHEMA
, TABLE_NAME
, TABLE_TYPE
FROM INFORMATION_SCHEMA.TABLES
使用这些视图,您可以轻松地比较两个数据库中的表:
SELECT a.TABLE_CATALOG
, a.TABLE_SCHEMA
, a.TABLE_NAME
, a.TABLE_TYPE
, b.TABLE_CATALOG
, b.TABLE_SCHEMA
, b.TABLE_NAME
, b.TABLE_TYPE
FROM OneDatabase.INFORMATION_SCHEMA.TABLES a
FULL OUTER JOIN TwoDatabase.INFORMATION_SCHEMA.TABLES b
ON a.TABLE_SCHEMA = b.TABLE_SCHEMA
AND a.TABLE_NAME = b.TABLE_NAME
如果数据库位于链接的单独服务器上,您应该可以使用Fully Qualified Table Name的所有四个部分来使用此查询。
答案 2 :(得分:1)
如果您的目的只是包含当前的数据库名称,为什么不只是:
SELECT DB_NAME(), SCHEMA_NAME(schema_id), name FROM sys.tables;
如果您打算从所有数据库中提取所有名称,我个人更喜欢这样的动态SQL而不是sp_msforeachdb
:
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += CHAR(13) + CHAR(10) + 'UNION ALL
SELECT ''' + name + ''', s.name, t.name
FROM ' + QUOTENAME(name) + '.sys.tables AS t
INNER JOIN ' + QUOTENAME(name) + '.sys.schemas AS s
ON t.schema_id = s.schema_id'
FROM sys.databases
WHERE database_id > 4;
SET @sql = STUFF(@sql, 1, 13, '');
PRINT @sql;
-- EXEC sp_executesql @sql;