我需要在一个表中查找SQL查询:
我尝试使用以下查询列出数据库角色,但我只得到一个数据库的结果。
select
rp.name as database_role,
mp.name as database_user
from
sys.database_role_members drm
join sys.database_principals rp
on (drm.role_principal_id = rp.principal_id)
join sys.database_principals mp
on (drm.member_principal_id = mp.principal_id)
答案 0 :(得分:0)
您获得了当前数据库的结果,因为这是目录视图的工作方式。另一方面,您可以使用由三部分组成的名称来查询其他数据库的目录视图。
例如,如果要从msdb
数据库中选择表,可以使用以下语法:
SELECT * FROM msdb.sys.tables
查询所有数据库
下一个问题是为所有数据库编写查询。不幸的是,没有“所有数据库”的参考,但是有一个无证的存储过程可以提供帮助。这是sp_MSforeachdb
。
请注意,短语undocumented
表示实现和参数列表可能会更改,或者可以随时删除该功能,因此在使用任何未记录的功能时要小心! / em>的
列出所有角色的查询如下所示:
EXEC sp_MSforeachdb
@command1 = '
INSERT INTO ##RoleTemp (db, database_role, database_user)
SELECT
''?'' AS db,
rp.NAME AS database_role,
mp.NAME AS database_user
FROM
[?].sys.database_role_members drm
INNER JOIN [?].sys.database_principals rp
ON (drm.role_principal_id = rp.principal_id)
INNER JOIN [?].sys.database_principals mp
ON (drm.member_principal_id = mp.principal_id);
'
SP将遍历所有数据库并运行每个数据库的查询。上述查询中的问号将替换为实际的数据库名称。
合并数据集
此查询存在一个小问题:它将返回多个结果(每个数据库一个结果)。
最后一步是将所有结果合并为一个结果。 sp_MSforeachdb
的参数多于上面的参数。要解决多结果问题,您可以使用@precommand
和@postcommand
参数。
@precommand
参数提供的查询只会在主查询之前运行一次,而@postcommand
将在结束时运行。
知道这一点,最终的查询将是:
EXEC sp_MSforeachdb
@precommand = N'CREATE TABLE ##RoleTemp (db VARCHAR(MAX), database_role VARCHAR(MAX), database_user VARCHAR(MAX));',
@command1 = '
INSERT INTO ##RoleTemp (db, database_role, database_user)
SELECT
''?'' AS db,
rp.NAME AS database_role,
mp.NAME AS database_user
FROM
[?].sys.database_role_members drm
INNER JOIN [?].sys.database_principals rp
ON (drm.role_principal_id = rp.principal_id)
INNER JOIN [?].sys.database_principals mp
ON (drm.member_principal_id = mp.principal_id);
',
@postcommand = 'SELECT * FROM ##RoleTemp; DROP TABLE ##RoleTemp;'
这将创建一个临时表,然后将所有数据库中的所有结果插入到该临时表中。 post命令选择插入临时表的所有记录,然后删除临时表。
我希望,这有助于解决您的问题。