我想查询我的sql server实例中所有数据库的数据库用户角色。我从sp_helpuser修改了一个查询:
select u.name
,case when (r.principal_id is null) then 'public' else r.name end
,l.default_database_name
,u.default_schema_name
,u.principal_id
from sys.database_principals u
left join (sys.database_role_members m join sys.database_principals r on m.role_principal_id = r.principal_id)
on m.member_principal_id = u.principal_id
left join sys.server_principals l on u.sid = l.sid
where u.type <> 'R'
如何将其修改为从所有数据库进行查询? sys.databases和sys.database_principals之间的链接是什么?
答案 0 :(得分:3)
您可以使用存储过程sp_msforeachdb
sp_msforeachdb:这是非常有用的 系统存储过程将 执行您传递给的任何SQL脚本 在SQL上的每个数据库中 服务器实例。存储过程 只是遍历数据库, 这写起来很简单,但它可以节省 你不必自己做。
为数据库名称添加一列,为数据库名称添加[?]占位符,然后在sp_msforeachdb
存储过程中执行脚本,如下所示:
EXECUTE sp_msforeachdb 'select ''[?]'' as DatabaseName,
u.name
,case when (r.principal_id is null) then ''public'' else r.name end
,l.default_database_name
,u.default_schema_name
,u.principal_id
from [?].sys.database_principals u
left join ([?].sys.database_role_members m join [?].sys.database_principals r on m.role_principal_id = r.principal_id)
on m.member_principal_id = u.principal_id
left join [?].sys.server_principals l on u.sid = l.sid
where u.type <> ''R'''
要在一个表中完成所有操作,您必须在一个数据库中创建一个表,我们将使用master
作为示例。
在master
数据库
Create Table master.dbo.userPermissionResults
(
....
)
然后只需将insert语句添加到查询的开头
EXECUTE sp_msforeachdb 'Insert Into master.dbo.userPermissionResults select ''[?]'' as DatabaseName,
u.name
,case when (r.principal_id is null) then ''public'' else r.name end
,l.default_database_name
,u.default_schema_name
,u.principal_id
from [?].sys.database_principals u
left join ([?].sys.database_role_members m join [?].sys.database_principals r on m.role_principal_id = r.principal_id)
on m.member_principal_id = u.principal_id
left join [?].sys.server_principals l on u.sid = l.sid
where u.type <> ''R'''
您必须为Insert
语句指定数据库名称,否则它将尝试将数据插入当前数据库。