サーバー上のスキーマを含むすべてのテーブルを一覧表示することは問題ありません
SELECT SCHEMA_NAME(schema_id), name FROM sys.tables
テーブルが存在するデータベースを特定するにはどうすればよいですか?
サーバー上のスキーマを含むすべてのテーブルを一覧表示することは問題ありません
SELECT SCHEMA_NAME(schema_id), name FROM sys.tables
テーブルが存在するデータベースを特定するにはどうすればよいですか?
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
参考までに、sp_msforeachdb proc は文書化されていないため、運用コードには使用しないでください。問題がないことをすばやく見つけるために、運用コードでは、この proc の独自のバージョンを展開してください。
Aaron Bertrand の投稿も参照してください。
サーバー上の別のデータベースに対して実行できるようにしたいクエリを作成していたときに、この問題に遭遇し、クエリにハードコーディングせずに他のデータベースの名前を含めました。
クエリは基本的に次のようになります。
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.
問題はOtherDB.sys.tables
、from 句で指定しても、DB_NAME()
常に現在のデータベースが返されることでした。はい、USE OtherDB
先頭に a を配置できましたが、別の方法があるように思われました。sys.databases
見つけられるすべての sys ビューを調べましたが、とにリンクするものは見つかりませんでしたsys.tables
。
私が最終的に見つけたのは、SQL ServerのINFORMATION_SCHEMA.TABLES
このビューには、最初の列としてデータベース名が含まれています( と呼ばれますTABLE_CATAOLG
)。
SELECT TABLE_CATALOG
, TABLE_SCHEMA
, TABLE_NAME
, TABLE_TYPE
FROM INFORMATION_SCHEMA.TABLES
これらのビューを使用すると、2 つのデータベースのテーブルを簡単に比較できます。
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
データベースがリンクされている別のサーバー上にある場合は、完全修飾テーブル名の 4 つの部分すべてを使用して、このクエリを使用できるはずです。
現在のデータベース名を含めるだけの場合は、次のようにしてください。
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;