Answers:
这是使用动态SQL的一种方法。如果没有迭代,实际上没有任何方法可以做到这一点,但是这种方法比未公开说明,不支持且有错误的选项(例如)sp_MSforeachdb
安全得多。
这将获得所有联机数据库的列表,映射的用户(如果存在),默认模式名称以及它们所属角色的逗号分隔列表。
DECLARE @name SYSNAME = N'your login name'; -- input param, presumably
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'UNION ALL SELECT N''' + REPLACE(name,'''','''''') + ''',
p.name, p.default_schema_name, STUFF((SELECT N'','' + r.name
FROM ' + QUOTENAME(name) + N'.sys.database_principals AS r
INNER JOIN ' + QUOTENAME(name) + N'.sys.database_role_members AS rm
ON r.principal_id = rm.role_principal_id
WHERE rm.member_principal_id = p.principal_id
FOR XML PATH, TYPE).value(N''.[1]'',''nvarchar(max)''),1,1,N'''')
FROM sys.server_principals AS sp
LEFT OUTER JOIN ' + QUOTENAME(name) + '.sys.database_principals AS p
ON sp.sid = p.sid
WHERE sp.name = @name '
FROM sys.databases WHERE [state] = 0;
SET @sql = STUFF(@sql, 1, 9, N'');
PRINT @sql;
EXEC master.sys.sp_executesql @sql, N'@name SYSNAME', @name;
该脚本是根据所提到的脚本进行的稍微修改,可以满足您的需求。将“ ThursdayClass”替换为您需要信息的登录名。 https://www.simple-talk.com/sql/sql-tools/the-sqlcmd-workbench/
SET NOCOUNT ON
CREATE TABLE #temp
(
SERVER_name SYSNAME NULL ,
Database_name SYSNAME NULL ,
UserName SYSNAME ,
GroupName SYSNAME ,
LoginName SYSNAME NULL ,
DefDBName SYSNAME NULL ,
DefSchemaName SYSNAME NULL ,
UserID INT ,
[SID] VARBINARY(85)
)
DECLARE @command VARCHAR(MAX)
--this will contain all the databases (and their sizes!)
--on a server
DECLARE @databases TABLE
(
Database_name VARCHAR(128) ,
Database_size INT ,
remarks VARCHAR(255)
)
INSERT INTO @databases--stock the table with the list of databases
EXEC sp_databases
SELECT @command = COALESCE(@command, '') + '
USE ' + database_name + '
insert into #temp (UserName,GroupName, LoginName,
DefDBName, DefSchemaName,UserID,[SID])
Execute sp_helpuser
UPDATE #TEMP SET database_name=DB_NAME(),
server_name=@@ServerName
where database_name is null
'
FROM @databases
EXECUTE ( @command )
SELECT loginname ,
UserName ,
Database_name
FROM #temp
WHERE LoginName = 'ThursdayClass'
尝试sp_dbpermissions。它可能会为您提供所需信息,但它会做您想做的事情。
安装完成后,运行此程序。
sp_dbpermissions @dbname = 'All', @LoginName = 'LoginName'
公平警告,目前它会进行“喜欢”匹配,因此,如果其他登录名相似且匹配,则您也会看到它们。例如MyLogin
和MyLoginForThis
都将匹配MyLogin
。如果这是一个问题,那么我有一个尚未发布的版本,您可以在此处关闭它。让我知道,我可以通过电子邮件将其发送给您。
这是一个Powershell解决方案:
import-module sqlps;
$s = new-object microsoft.sqlserver.management.smo.server '.'
foreach ($db in $s.Databases | where {$_.IsAccessible -eq $true}) {
$u = $db.users | where {$_.Login -eq 'foobar'}
if ($u -ne $null) { #login is mapped to a user in the db
foreach ($role in $db.Roles) {
if ($role.EnumMembers() -contains $u.Name) {
$u | select parent, @{name="role";expression={$role.name}}, name
}
}
}
}
我正在寻找类似的答案并找到了这个答案:https : //www.pythian.com/blog/httpconsultingblogs-emc-comjamiethomsonarchive20070209sql-server-2005_3a00_-view-all-permissions-_2800_2_2900_-aspx/。是的,它使用了可怕的sp_MSforeachDB,但是我认为那个人有时会受到不好的说唱... ;-)
我将在此处发布SQL以方便复制粘贴(我不为此而功劳,只是使其易于访问!):
DECLARE @DB_Users TABLE (DBName sysname, UserName sysname, LoginType sysname
, AssociatedRole varchar(max), create_date datetime, modify_date datetime)
INSERT @DB_Users
EXEC sp_MSforeachdb
'use [?]
SELECT ''?'' AS DB_Name,
case prin.name when ''dbo'' then prin.name + '' (''
+ (select SUSER_SNAME(owner_sid) from master.sys.databases where name =''?'') + '')''
else prin.name end AS UserName,
prin.type_desc AS LoginType,
isnull(USER_NAME(mem.role_principal_id),'''') AS AssociatedRole,
create_date, modify_date
FROM sys.database_principals prin
LEFT OUTER JOIN sys.database_role_members mem
ON prin.principal_id=mem.member_principal_id
WHERE prin.sid IS NOT NULL and prin.sid NOT IN (0x00)
and prin.is_fixed_role <> 1 AND prin.name NOT LIKE ''##%'''
SELECT dbname, username, logintype, create_date, modify_date,
STUFF((SELECT ',' + CONVERT(VARCHAR(500), associatedrole)
FROM @DB_Users user2
WHERE user1.DBName=user2.DBName AND user1.UserName=user2.UserName
FOR XML PATH('')
),1,1,'') AS Permissions_user
FROM @DB_Users user1
WHERE user1.UserName = N'<put your login-name here!>'
GROUP BY dbname, username, logintype, create_date, modify_date
ORDER BY DBName, username
下面的查询应返回所请求的DbName的映射
SELECT 'DbName', dbPri.name, dbPri1.name
FROM [DbName].sys.database_principals dbPri
JOIN [DbName].sys.database_role_members dbRoleMem ON dbRoleMem.member_principal_id =
dbPri.principal_id
JOIN [DbName].sys.database_principals dbPri1 ON dbPri1.principal_id =
dbRoleMem.role_principal_id
WHERE dbPri.name != 'dbo'
改进的查询如下
declare @sql varchar(Max)
set @sql = 'use ? SELECT ''?'', dbPri.name, dbPri1.name
FROM sys.database_principals dbPri
JOIN sys.database_role_members dbRoleMem ON
dbRoleMem.member_principal_id =
dbPri.principal_id
JOIN sys.database_principals dbPri1 ON dbPri1.principal_id =
dbRoleMem.role_principal_id
WHERE dbPri.name != ''dbo'''
EXEC sp_MSforeachdb @sql