【问题标题】:How to get the list of all database users如何获取所有数据库用户的列表
【发布时间】:2013-09-18 08:04:59
【问题描述】:

我将获取所有用户的列表,包括 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' 条件。

如何更改此查询,还是应该使用另一个查询?

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    对于 SQL Server 所有者,您应该可以使用:

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

    对于 SQL 用户列表:

    select * from master.sys.server_principals
    

    参考。 SQL Server Tip: How to find the owner of a database through T-SQL

    How do you test for the existence of a user in SQL Server?

    【讨论】:

    • master.sys.server_principals 产生服务器登录列表,不是数据库用户。
    【解决方案2】:
    EXEC sp_helpuser
    

    SELECT * FROM sysusers
    

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

    【讨论】:

    • EXEC sp_helpuser 非常适合我无法访问所有 sys 表的 RDS - 谢谢!
    【解决方案3】:

    每当您在 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
    

    【讨论】:

      【解决方案4】:
      SELECT name FROM sys.database_principals WHERE
      type_desc = 'SQL_USER' AND default_schema_name = 'dbo'
      

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

      【讨论】:

      • 适用于 SQL Azure 数据库
      • 这个过滤器是不正确的,因为你只获得了 default_schema_name = 'dbo' 的用户,但是你创建的用户也可以有不同的 default_schema_name(dbo 是默认值,但你可以创建另一个)
      【解决方案5】:

      去这个:

       SELECT name,type_desc FROM sys.sql_logins
      

      【讨论】:

        【解决方案6】:

        我尽量避免使用“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
        

        希望这会有所帮助。

        【讨论】:

          【解决方案7】:

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

          EXEC sp_MSforeachdb 'USE ? <QUERY HERE>'
          

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-01-20
            • 2023-03-24
            • 2017-11-04
            • 1970-01-01
            • 2013-01-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多