84

我将获取所有用户的列表,包括 Windows 用户和“sa”,他们有权访问 MS SQL Server 中的特定数据库。基本上,我希望列表看起来像中显示的内容SQL Server Management Studio(即展开时显示的列表[databse] -> Security -> Users),但有一个重要例外:我不想'dbo'在列表中看到 。相反,我想查看拥有数据库的实际用户。因此,例如,如果 'sa' 是'dbo','sa'必须包含在列表中而不是'dbo'. 另一个不容错过的注意事项是,SQL Server Management Studio除了 SQL 用户之外,列表中通常还显示 Windows 用户,我希望这些用户也包括在内。

到目前为止,我已经能够提出以下查询:

SELECT * FROM sys.database_principals where (type='S' or type = 'U')

这个查询几乎是正确的,但问题是它不满足'dbo'条件。

如何更改此查询或应该使用另一个查询?

4

7 回答 7

119

对于 SQL Server 所有者,您应该能够使用:

select suser_sname(owner_sid) as 'Owner', state_desc, *
from sys.databases

对于 SQL 用户列表:

select * from master.sys.server_principals

参考。 SQL Server 提示:如何通过 T-SQL 找到数据库的所有者

如何在 SQL Server 中测试用户是否存在?

于 2013-09-18T08:16:59.020 回答
45
EXEC sp_helpuser

或者

SELECT * FROM sysusers

这两个都选择当前数据库(而不是服务器)的所有用户。

于 2017-06-06T10:13:25.873 回答
13

每当您在 GUI (SSMS) 中“看到”某些内容并且您喜欢“这就是我需要的”时,您始终可以运行 Sql Profiler 来查找所使用的查询。

运行 Sql Profiler。当然,将其附加到您的数据库中。

然后右键单击 GUI(在 SSMS 中)并单击“刷新”。
然后去看看 Profiler “捕获”了什么。

当我在 MyDatabase / Security / Users 中并单击“用户”上的“刷新”时,我得到了以下信息。

同样,我没有提出 WHERE 子句和 LEFT OUTER JOIN,它是 SSMS 查询的一部分。这个查询是微软的某个人写的(你知道,了解产品内外的偷窥者,也就是专家),所以他们熟悉数据库中所有奇怪的“标志”。

但是 SSMS/GUI -> Sql Profiler 技巧适用于许多场景。

SELECT
u.name AS [Name],
'Server[@Name=' + quotename(CAST(
        serverproperty(N'Servername')
       AS sysname),'''') + ']' + '/Database[@Name=' + quotename(db_name(),'''') + ']' + '/User[@Name=' + quotename(u.name,'''') + ']' AS [Urn],
u.create_date AS [CreateDate],
u.principal_id AS [ID],
CAST(CASE dp.state WHEN N'G' THEN 1 WHEN 'W' THEN 1 ELSE 0 END AS bit) AS [HasDBAccess]
FROM
sys.database_principals AS u
LEFT OUTER JOIN sys.database_permissions AS dp ON dp.grantee_principal_id = u.principal_id and dp.type = 'CO'
WHERE
(u.type in ('U', 'S', 'G', 'C', 'K' ,'E', 'X'))
ORDER BY
[Name] ASC
于 2018-09-17T15:36:17.567 回答
6
SELECT name FROM sys.database_principals WHERE
type_desc = 'SQL_USER' AND default_schema_name = 'dbo'

这将选择管理员创建的 SQL 服务器中的所有用户!

于 2016-06-05T19:03:11.303 回答
5

去做这个:

 SELECT name,type_desc FROM sys.sql_logins
于 2019-04-05T05:09:13.223 回答
2

我尽量避免使用“SELECT *”选项,只提取我想要或需要的数据。下面的代码是我使用的,您可以根据需要剔除或添加列和别名。

我还使用“IIF”(即时如果)将二进制 0 或 1 替换为是或否。它只是让可能想要此信息的非技术人员更容易阅读。

这是我使用的:

SELECT 
    name AS 'User'
  , PRINCIPAL_ID
  , type AS 'User Type'
  , type_desc AS 'Login Type'
  , CAST(create_date AS DATE) AS 'Date Created' 
  , default_database_name AS 'Database Name'
  , IIF(is_fixed_role LIKE 0, 'No', 'Yes') AS 'Is Active'
FROM master.sys.server_principals
WHERE type LIKE 's' OR type LIKE 'u'
ORDER BY [User], [Database Name]; 
GO

希望这可以帮助。

于 2018-08-28T20:11:03.003 回答
0

要运行返回单个数据库用户的查询,请尝试以下操作:

EXEC sp_MSforeachdb 'USE ? <QUERY HERE>'

这将为每个数据库运行一个查询(并返回一个结果)。因此,要获取所有用户(可能有很多您不感兴趣的内部用户和角色,请尝试:

EXEC sp_MSforeachdb 'USE ?; SELECT DB_NAME(), * FROM sys.database_principals;'

只需应用其他回复中提到的过滤器即可获得您正在寻找的子集。

于 2022-02-10T10:16:33.180 回答