我必须对多个数据库运行各种查询并收集结果 作为结果集,因此
sp_MSforeach
方法行不通。我实际上是在收集有关这些服务器中的数据库、模式和对象的数据,以提供一些实用功能。
信息模式在工作时效果很好,但对于某些事情,您需要
sys
视图,例如sys.synonyms
。这个,通过链接服务器:
select *
from <remote_server>.<database>.sys.synonyms
这让我,例如,
schema_id
。我需要从 schema_id
中获取架构名称。我不能使用 SCHEMA_NAME()
因为它在该服务器上的这个数据库的上下文中工作,而不是在远程服务器上的远程链接数据库的上下文中工作。我需要的是这样的东西(发明的语法):
select
*,
<remote_server>.<database>.SCHEMA_NAME(schema_id)
from
<remote_server>.<database>.sys.synonyms
据我所知,不存在。
我可以使用
information_schema.schemata
视图,除了
information_schema
结果的模式信息。所以有几个问题,首先,当
schema_id
从远程服务器获取时,如何从 schema_id
获取架构名称?
其次,有没有人知道任何全面的文档或者更好的一本好书,它涵盖了这些目录视图,这些视图取代了旧的
information_schema
视图,因为使用它们是一种皇家痛苦。
好吧,您似乎想在一个结果集中查询多个数据库和/或服务器的系统视图。这总是很困难,因为它需要包含每个数据库的大
UNION ALL
查询,如果您只在变量中使用它们,那么您需要动态 SQL。
让我们假设您在表变量中有数据库
DECLARE @dbs TABLE (server sysname, dbname sysname);
然后生成所有这些的大
UNION ALL
并执行它。
DECLARE @sql nvarchar(max);
SELECT @sql = STRING_AGG(CAST('
SELECT
schema_id,
name,
db = ' + QUOTENAME(dbs.dbname, '''') + '
FROM ' + QUOTENAME(dbs.server) + '.' + QUOTENAME(dbs.dbname) + '.sys.schemas
' AS nvarchar(max)), '
UNION ALL')
FROM @dbs dbs;
PRINT @sql; -- your friend
EXEC sp_executesql @sql;
如果你有任何参数,包括表值参数,你可以通过
sp_executesql
传递它们。不要不将它们作为文本注入。
例如在所有数据库中查找
@schema_id
:
DECLARE @sql nvarchar(max);
SELECT @sql = STRING_AGG(CAST('
SELECT
id,
name,
db = ' + QUOTENAME(dbs.dbname, '''') + '
FROM ' + QUOTENAME(dbs.server) + '.' + QUOTENAME(dbs.dbname) + '.sys.schemas
WHERE schema_id = @schema_id
' AS nvarchar(max)), '
UNION ALL')
FROM @dbs dbs;
PRINT @sql; -- your friend
EXEC sp_executesql @sql,
N'@schema_id int',
@schema_id = @schema_id;